来源:www.cncfan.com | 2006-1-11 | (有5174人读过)
信号是发生某件事时对进程的通知,它不可以被预知。信号可以来自其它进程或者进程本身,也可以是来自内核。
每个信号都有一个处理办法(disposition),也称作与信号关联的行为(action),一般有三种处理方法:
1 提供一个函数(signal handler),在信号发生时调用,这称之为捕获(catching)。
2 设置信号的处理办法为SIG_IGN,忽略它,但有两种信号是不能忽略的:SIGKILL、SIGSTOP。
3 SIG_DFL可以设置缺省处理办法,一般是收到信号时终止进程。当然,也可以忽略它们,例如SIGCHLD和SIGURG。
POSIX中定义信号处理函数用sigaction函数,处理函数的指针做为填充在做为参数之一的struct sigaction结构中,当然还有函数所对应的需要处理的信号,原型如下:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
UNP中为sigaction做了一个包裹函数:
Sigfunc *signal(int signo, Sigfunc *func);
它与非POSIX的signal函数一致,就是向操作系统登记要处理的信号。信号处理函数在登记完成后便一直有效。信号处理函数在执行时,可以通过设置sa_mask来指定要屏蔽的其实信号。此时被屏蔽(阻塞)的信号是不排队的。当然,在实时UNIX系统中不会阻塞信号,所有的信号排队接受处理。
UNIX对信号的处理不排队,这个特性就是说:当同时有若干个信号,只捕获第一个,其它的就被抛弃了。可以想像一个服务器同时连接着很多客户机,当若干个客户同时断开连接,服务器处理这些客户的进程结束后几乎同时向父进程发送SIGCHLD信号。只有第一个SIGCHLD被处理了,其它的信号会屏蔽掉,子进程仍会处于僵尸状态(Zombie)。
处理这种情况要使用waitpid函数,它比wait提供更多控制机制,下面就是一个典型的SIGCHLD信号处理函数:
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG))>0)
printf("child %d terminated.\n", pid);
return ;
}
waitpid中pid设为-1表示等侍第一个终止的子进程,WNOHANG表示在没有已终止子进程时不要阻塞。
|