如果信号的处理动作是用户自定义函数,在信号递达时就调用此函数,这成为捕捉信号。
sighandler和main函数使用不同的堆栈空间,它们之间不存在调用与被调用关系,是两个独立的控制流程。
当进程从内核态返回用户态时,会对信息进行检测并处理。
sigaction函数:功能:读取和修改与指定信号相关联的处理动作。
函数原型:int sigaction(int signo,const struct sigaction *act,struct sigaction *oact);
返回值:调用成功则返回0;出错则返回-1。
参数:signo是指定信号的编号,若act指针非空,则根据act修改该信号的处理动作。若oact指针非空,则通过oact传出该指针原来的处理动作。act和oact都指向sigaction结构体。
当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么它将被阻塞到当前处理结束为止。pause函数:功能:使调用进程挂起,直到有信号递达。
函数原型:int pause(void);
返回值:pause只有出错的返回值。错误码EINTR表示“被信号中断”。
代码实例:用alarm和pause实现sleep,称为mysleep。
#include <stdio.h> #include<signal.h> #include<unistd.h> void sig_alrm(int signo){ //do nothing } unsigned int mysleep(unsigned int nsecs){ struct sigaction act,oact; unsigned int unslept = 0; act.sa_handler = sig_alrm; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM,&act,&oact); alarm(nsecs); pause(); unslept = alarm(0); sigaction(SIGALRM,&oact,NULL); return unslept; } int main(){ while(1){ mysleep(5); printf("5 seconds passed\n"); } return 0; }结果演示:
pause函数返回-1,然后调用alarm(0)取消闹钟,调用sigaction恢复SIGALRM信号以前的处理动作。
