网络编程中利用信号处理技术消灭僵尸进程

文章介绍了如何使用`fork()`函数创建子进程,强调了如果不正确处理子进程结束状态,会导致僵尸进程。还讨论了`sleep()`函数的中断机制,指出进程在睡眠期间可能被信号唤醒。
摘要由CSDN通过智能技术生成

利用fork()函数来创建子进程,若不主动获取子进程的结束状态值,就会出现僵尸进程。

fork函数的定义如下:

fork函数是一个系统调用函数,用于创建一个新的进程,新进程是原进程的一个副本。它在父进程中返回新创建的子进程的进程ID,在子进程中返回0。这样,通过fork函数的调用,一个进程可以变成两个几乎完全相同的进程,每个进程都可以继续执行fork调用之后的代码。

注意:

fork函数创建的子进程和父进程拥有相同的父进程,即它们的父进程是同一个进程。子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程的上下文、代码段、进程堆栈、内存信息、打开的文件描述符、符号控制设定、进程优先级、进程组号、当前工作目录等。但是子进程和父进程是两个独立的进程,它们有不同的进程ID,可以独立运行,互不干扰。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

void read_childproc(int sig)
{
	int status;
	pid_t id=waitpid(-1, &status, WNOHANG);
	if(WIFEXITED(status))
	{
		printf("Removed proc id: %d \n", id);
		printf("Child send: %d \n", WEXITSTATUS(status));
	}
}

int main(int argc, char *argv[])
{
	pid_t pid;
	struct sigaction act;
	act.sa_handler=read_childproc;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	sigaction(SIGCHLD, &act, 0);

	pid=fork();
	if(pid==0)
	{
		puts("Hi! I'm child process");
		sleep(10);
		return 12;
	}
	else
	{
		printf("Child proc id: %d \n", pid);
		pid=fork();
		if(pid==0)
		{
			puts("Hi! I'm child process");
			sleep(10);
			exit(24);
		}
		else
		{
			int i;
			printf("Child proc id: %d \n", pid);
			for(i=0; i<5; i++)
			{
				puts("wait...");
				sleep(5);
			}
		}
	}
	return 0;
}

/*
root@my_linux:/home/swyoon/tcpip# gcc remove_zombie.c -o zombie
root@my_linux:/home/swyoon/tcpip# ./zombie
Hi! I'm child process
Child proc id: 9529 
Hi! I'm child process
Child proc id: 9530 
wait...
wait...
Removed proc id: 9530 
Child send: 24 
wait...
Removed proc id: 9529 
Child send: 12 
wait...
wait...

*/

由上述代码可以看出,子进程为变成僵尸进程。

 

Sleep()函数的中断时机:

当进程被信号唤醒时,`sleep`函数不会立即执行完毕。`sleep`函数会在进程被唤醒后继续执行剩余的时间,直到睡眠时间结束或者被其他信号打断。

`sleep`函数会将进程挂起,直到指定的时间到达或者被信号中断。当进程被信号唤醒时,它会检查是否有未处理的信号,并根据信号的处理方式来处理。如果信号的处理方式是默认的,进程会终止或者执行默认操作。如果信号的处理方式是忽略或者捕获,进程会继续执行剩余的时间。

需要注意的是,`sleep`函数是一个可中断的睡眠函数。如果进程在睡眠过程中收到了某些信号(如`SIGALRM`),则会被信号中断并提前结束睡眠。在这种情况下,`sleep`函数会返回剩余的睡眠时间。 

注意:输出的顺序不唯一,这跟操作系统有关。

子进程从调用fork()后开始执行,子进程和父进程同时进行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值