信号
对信号的三种操作:忽略捕获 默认
void *Signal(int signo, (void (*func)(int) ) ) (int )
不可靠信号:信号已发生,但进程不知道。
多个信号的处理问题
在某个信号处理期间来了此种信号
在某个信号处理期间来了另一种信号
信号对系统调用的影响:1).设置errno返回;2)重启调用。
可重入函数:被信号中断后重启调用。
不是可重入条件:1).使用静态数据
2).调用malloc,free类函数
3).标准I/O函数。
SIGCHD
SIGCHLD
raise(pid_t pid, int signo)
kill(int signo)
设置signon =0 , kill()用来检测某个特定进程是否仍旧存在。但ID会被重复利用,现有的ID可能并不是你想要的。这种测试不是原子操作。
unsigned int alrm(unsigned int second) ;
int pause(void);
使用alrm(), pause()信号实现sleep()功能。
讲述了使用信号的各种注意事项。
1).使用arlm()时,若前面设置了alrm().则会刷新前面的。
2).信号修改时要备份还原的问题。
3).arlm() 与pause()的竞争条件问题。
sleep2()使用setjmp(),longjmp()来解决竞争问题。即使pasue()没有执行过,发生alrm()时也会返回。但是没有解决1,2问题。这个貌似是留给读者的问题。
但是如果arlm()中断了其他信号,随之而来的longjmp()就会提早的结束此信号的处理。这个设计多信号的交互问题。
在longjmp()调用时会设置信号屏蔽,在调用结束时有的系统会恢复信号屏蔽字,有的则不管。这就引出了sigsetjmp().siglongjmp()。
alrm()还用来设置设备的读写超时时间设置。
1).涉及竞争条件问题。
2).系统调用是否是可重启的问题。
如果设置了alrm()后,程序阻塞在read()之前,那就会导致read()无法读到数据,解决办法是alrm()设置的时间长一点,如60S。
如果系统调用是重启的,那设置alrm()将不会起到作用。在SIGALRM处理函数返回时,read()操作并不会被中断。这种情况可以使用setjmp(),longjmp()解决。