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

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

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

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

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

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

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

如下代码:

#include 
#include 
#include 

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 
#include 
#include 

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 something
	while(1);	// 使程序不退出
	return 0;
}



你可能感兴趣的:(C/C++)