信号总结(一)

信号

对信号的三种操作:忽略捕获  默认

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()解决。

 

 

 

 

原文地址:https://www.cnblogs.com/ppazhang/p/3621936.html