linux 中 signal 用法回收子进程结束产生的僵尸进程

来源:互联网 发布:java array.tostring 编辑:程序博客网 时间:2024/06/05 15:42

在linux 中, 使用多进程时,大家都知道, 子进程和父进程的结束顺序不同, 会出现不同的情况, 如下:

1. 当父进程比子进程先结束时, 子进程会自动依托于跟进程(init进程)管理, 这时子进程叫做"孤儿进程", 程序没有任何问题.

孤儿进程: 是完善的进程, 无任何危害的.

2. 当子进程比父进程先结束时, 子进程就会成为 Z 进程(僵尸进程).

僵尸进程: 不占用内存和CPU, 但是会占用进程任务管理树上的一个节点(这个节点很重要, 如一些CPU中允许创建固定数量进程, 占用一个就会少一个了), 

这时应该如何去回收这个僵尸进程呢? linux 提供了wait()函数数据去回收僵尸进程,  使用signal()函数来接收子进程返回的信号量(子进程结束时发出的信号量为17).

如下代码:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>void sigfun(int sig){int status;printf("%s[%d]:recv sig = %d\n", __FUNCTION__, __LINE__, sig);wait(&status);// 回收子进程printf("%s[%d]:status = %d\n", __FUNCTION__, __LINE__, WEXITSTATUS(status));}int main(){if (fork())// 父进程{signal(17, sigfun);// 注册信号量接收, 当接收到17的信号量时会执行sigfun函数printf("parent process doing while(1)\n");while(1);}else// 子进程{printf("child process doing sleep(5)\n");sleep(5);printf("child process exit(10)\n");exit(10);}return 0;}

其实signal函数可以在任何程序初始化注册使用, 用于接收固定的信号量.

如两个有关系的进程A 和B ,  当B 执行到进一个特别的地方时, 就发送一个固定的信号给A, A再做出现应的处理.

再如, 与数据库/php程序交互时, 你的程序不知道什么时候数据库什么时候有更新, 也不知道什么时候去取数据库, 如果是定时1分钟去取数据库, 可能会一次取到很多数据, 但更多的时候可能是什么也取不到. 这时就可以使用signal函数,来接收数据库/PHP传过来的固定信号量, 当收到信号时再去取数据库, 这样就方便很多很多.

如下代码, 是一个测试程序来接收用户对其进行发送的信号量, 程序中测试了50-54 这5个信号量, 当在终端中, 使用killall 进程名 -n  (n 为信号量) 对进程发送信号量

#include <stdio.h>#include <stdlib.h>#include <unistd.h>void sigfun(int sig){int status;printf("%s[%d]:recv sig = %d\n", __FUNCTION__, __LINE__, sig);}int main(){signal(50, sigfun);// 注册信号量接收, 当接收到17的信号量时会执行sigfun函数signal(51, sigfun);signal(52, sigfun);signal(53, sigfun);signal(54, sigfun);// TODO: do somethingwhile(1);// 使程序不退出return 0;}



原创粉丝点击