循序渐进学unix——上机记录(五),signal
本文的主题是unix中的基本信号处理(signal)。
在Unix中,一个进程可以向另一个进程发送信号,接收进程再收到信号后可以根据配置做出相应反应。这也是一种通信机制。
涉及到的主要函数有:
- signal,配置当前进程,在收到什么信号时执行什么函数。第一个参数为想要处理的信号,第二个参数为待执行函数名。
- kill,向指定pid的进程发送一个指定信号。(子进程的pid即父进程中fork的返回值)
- sigaction,使用signal定义的动作函数只能有一个int型参数,代表信号值。如果想获得更多信息,可使用sigaction。它与signal功能类似,但是传递了更多信息。(见后文示例代码)。
1,Basic use。可通过在命令行提供参数来选择对信号的处理:默认,忽略,或执行某一函数。
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<signal.h> #include<stdlib.h> void signalHandler(int signum) { printf("In signalHandler, PID=%d, signum=%d.n", getpid(), signum); } void main(int argn, char** argv) { pid_t val_fork; int choice = -1; if(argn>1)choice = atoi(argv[1]); if((val_fork=fork())==0) { printf("In fils, before 'signal()'.n"); if(choice==0) signal(SIGUSR1, SIG_DFL);//Invoke default action else if(choice==1) signal(SIGUSR1, SIG_IGN);//Ignore signals else signal(SIGUSR1, signalHandler);//Call user defined function. printf("In fils, after 'signal()'.n"); printf("In fils, sleep for keeping aliven"); sleep(5); printf("In fils, exit.n"); exit(0); } else { printf("In pere, sleep for leaving enough time to my son.n"); sleep(3); printf("In pere, before kill().n"); kill(val_fork, SIGUSR1); if(choice==0) printf("In pere, OMG my son terminated himself!n"); else if(choice==1) printf("In pere, OMG my son ignored my knife!n"); else printf("In pere, I've just let my son execute a function!n"); } }
2,尝试在收到信号后显示发送信号进程的id。这里我们就不得不使用sigaction了。请通过man查看相关数据结构。
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<signal.h> #include<stdlib.h> void signalHandler(int signum, siginfo_t* siginfo, void* ucontent) { printf("In signalHandler, PID=%d, signum=%d, sending process=%d.n", getpid(), signum, siginfo->si_pid); } void main(int argn, char** argv) { pid_t val_fork; int choice = -1; struct sigaction sa; sa.sa_sigaction=signalHandler; sa.sa_flags=SA_SIGINFO; if(argn>1)choice = atoi(argv[1]); if((val_fork=fork())==0) { printf("In fils, before 'signal()'.n"); if(choice==0) signal(SIGUSR1, SIG_DFL);//Invoke default action else if(choice==1) signal(SIGUSR1, SIG_IGN);//Ignore signals else sigaction(SIGUSR1, &sa, NULL);//Call user defined function. printf("In fils, after 'signal()'.n"); printf("In fils, sleep for keeping aliven"); while(1)sleep(5); printf("In fils, exit.n"); exit(0); } else { printf("In pere, pid=%d, sleep for leaving enough time to my son.n", getpid()); sleep(3); printf("In pere, before kill().n"); kill(val_fork, SIGUSR1); if(choice==0) printf("In pere, OMG my son terminated himself!n"); else if(choice==1) printf("In pere, OMG my son ignored my knife!n"); else printf("In pere, I've just let my son execute a function!n"); } }
3,实现无阻塞通信。进程B执行自己的任意任务。进程A向pipe中写入信息并通过signal通知B,B收到信号后立即读取pipe中的信息。
<span style="f