Linux中信号处理(二、kill()函数)

前一篇有关信号的blog Linux中信号处理(一)中已经大概的分析了信号基本处理方法,已经signal的解析和绑定处理函数;这一篇blog来复习下信号中常用到的几个函数;

kill函数将信号发射给指定进程或者进程组,,raise函数则把信号发送给自己;raise函数比较好理解,raise(int signo);kill(pid_t pid, int signo)函数就有点复杂了。其实这个函数很类似前面进程中涉及到的 waitpid()函数Linux中进程控制函数:wait()和waitpid();下面着重来看下kill函数;

int kill(pid_t pid, int signo);

a、pid > 0 , 信号发送给pid进程;

b、pid == 0, 把信号发送给本进程(自己)所在的进程组中所有进程,不包括系统进程;

c、pid < 0 , 把信号发送给组id 为 -pid 的进程组中所有进程;

d、pid == -1,把信号发送给所有进程,除系统进程外(9和19号进程有些信号不接受)

前面复习了进程,所以这里特意挑出SIGCHLD信号来把信号和进程链接起来复习;当子进程退出时会发出一个SIGCHLD信号,这时候父进程可以调用wait函数来回收子进程的资源,避免子进程变成僵死进程;

下面的代码是打印下wait函数得到的退出码;

#include"common.h" void print_status(int exitCode) {if (WIFEXITED(exitCode))printf("normal termination, exitCode:%d\n", WEXITSTATUS(exitCode));else if (WIFSIGNALED(exitCode))printf("abnormal termination, signal number:%d\n", WEXITSTATUS(exitCode));else if (WIFSTOPPED(exitCode))printf("child stopped, signal number = %d\n", WSTOPSIG(exitCode)); }

下面的代码是核心

#include"common.h" void waitChild(int signo)// 把SIGCHLD信号和该函数绑定,当父进程接受到SIGCHLD信号后调用该函数,主要是回收子进程资源 {if (signo == SIGCHLD){wait(&status);}print_status(status);// 调用上面代码,打印退出码 } void testInt(int signo)// 和ctrl + c, SIGINT信号绑定的函数 {printf("ctrl+c pid:%d\n", getpid()); } void testTstp(int signo)// 和ctrl + c,SIGTSTP信号绑定的函数 {printf("ctrl+z pid:%d\n", getpid()); } int main(void) {pid_t pid;if (0 > (pid = fork())){// 创建子进程fprintf(stderr, "fork error!\n");exit(1);}else if(0 == pid){// 子进程操作区域sleep(2);// 睡眠2秒,让父进程为SIGCHLD信号绑定好函数printf("I am is child! pid is %d\n", getpid());if (SIG_ERR == signal(SIGTSTP, testTstp)){ // 子进程中也让SIGTSTP信号绑定testTstp函数,主要是测试kill发信号给进程组fprintf(stderr, "signal sigtstp error!\n");exit(-1);}printf("send sigint to process group!\n");// 利用kill函数 发信号给父进程(打印语句中不应该有group)if (-1 == kill(getppid(), SIGINT))fprintf(stderr, "kill sigint error!\n");printf("send sigtstp to process group!\n");// 利用kill函数发送信号给自己所在的进程组//if (-1 == kill(0, SIGTSTP))fprintf(stderr, "kill sigint error!\n");if (-1 == kill(-(getgid()), SIGTSTP))fprintf(stderr, "kill sigint error!\n");exit(123);// 退出,退出码为 123}else{// 父进程操作区域printf("I am is parent! pid is %d\n", getpid());if (SIG_ERR == signal(SIGCHLD, waitChild)){ // 让SIGCHLD信号绑定waitChild函数fprintf(stderr, "signal error!\n");exit(-1);}if (SIG_ERR == signal(SIGINT, testInt)){ // 让SIGINT 信号绑定testIntfprintf(stderr, "signal sigint error!\n");exit(-1);}if (SIG_ERR == signal(SIGTSTP, testTstp)){ // 让SIGTSTP 信号绑定testTstpfprintf(stderr, "signal sigtstp error!\n");exit(-1);}while(1) // 死循环,等待信号pause();}return 0; }

运行结果:

从上面结果可以看出:

1、子进程把SIGINT信号发送给父进程,父进程调用了绑定的testInt()函数,打印了 pid为1364;

2、子进程把SIGTSTP信号发送给子进程所在的进程组(新fork的子进程默认和父进程在同一个进程组),可以看出父进程和子进程都调用了testTstp()函数,打印的pid分别为:1364和1365;

3、子进程退出时,发送了一个SIGCHLD信号给父进程(这是系统默认会发送的),父进程调用了绑定的waitChild()函数打印了退出码为:123;

转载请注明作者和原文出处,原文地址:

若有不正确之处,望大家指正,共同学习!谢谢!!!

可是,我却迈不开步伐,怎么也走不出那个圈……

Linux中信号处理(二、kill()函数)

相关文章:

你感兴趣的文章:

标签云: