在Linux中简单实现回收子进程

在Linux中简单实现回收子进程

2023年8月2日发(作者:)

在Linux中简单实现回收⼦进程学习到wait函数了,这个函数的作⽤是⽤来回收进程。⼀般来说,正常退出的进程是不需要我们来专门回收的。但是进程有这两种:孤⼉进程和僵⼫进程。孤⼉进程:通俗点说就是⽗进程先于⼦进程死亡。此时⼦进程就成为孤⼉进程。这时候⼦进程的⽗进程就是init进程了。这个过程(⽗进程死亡后⼦进程的⽗进程变为init)称为init进程领养孤⼉进程。僵⼫进程进程终⽌,但是⽗进程并未进⾏回收操作。⼦进程的残留资源(PCB)存在于内核中,成为僵⼫进程。就是⼉⼦死了,但是⽗亲不收⼫。这⾥要注重理解的是:僵⼫进程实际上是结束的进程。所以,我们能⽤kill命令结束它么?不能!结束⼀个已经结束的进程。怎么能⾏呢?请看下列代码:#include #include #include int p = 111;//pid_t fork(void);//在⽗进程中返回⼦进程的id,在⼦进程返回0(没有⼦进程了嘛,因为)。int main(int argc, char*argv[])//有⽤户指定创建多少个⼦进程{ printf("hello from Create_N_subprocesses!n"); if (argc < 2) { printf("Too few parametersn"); exit(1); } int i, n = atoi(argv[1]); for (i = 0; i < n; i++) { if (0 == fork())//⽗进程中返回的不是0,继续执⾏for循环;在⼦进程中返回0,for循环结束。 { break; } } //基本上每个⽗⼦进程是同时进⾏。所以睡眠时间依次递增。 sleep(i); if (i < n)//⽗进程不能算在⾥⾯ { p++;//这⾥改变p的值 printf("I am the %d process.n p = %dn", i + 1, p);//这⾥的每个p都⼀样,哪怕每次p都会⾃增 } else { printf("my father process n p = %dn", p);//但是这⾥还是会输出111 } /* p⽤来验证⽗⼦之间可以⽤静态变量传递消息么? 答案是不可以,因为date段是独⽴的。 ⽗⼦之间遵循读时共享,写是独⽴的原则。 */ return 0;}这是⼀段⽤于创建N个⼦进程的程序代码。并且验证⽗⼦进程之间能够进⾏资源共享的资源共享⽅式是:读时共享写时独⽴。这些都不是重点。重点是,这个程序执⾏后会产⽣N个僵⼫进程。为什么?因为我们没有进⾏回收。怎么回收?⽤wait()函数。wait函数:该函数有三个功能:1.阻塞等待⼦进程退出 (如果该⼦进程没有死亡,⽗进程阻塞,不做其他的事。)2.回收⼦进程残留资源3.获取⼦进程结束状态(退出原因)。原型:pid_t wait(int *status);返回值:成功:清理掉的⼦进程ID;失败:-1 (没有⼦进程)需要注意的是:回收进程的⼯作是由当前进程的⽗进程来做。调⽤⼀次wait函数只会回收⼀个进程,若是多个进程死亡,wait函数只会回收最先死亡的那个进程。上代码:#include #include #include #include #include

int main(){ int status; int i = 0; pid_t pid_1, pid_2;

for (; i != 1; i++) { pid_1 = fork(); if (!pid_1) { break; } } if (i < 1) { sleep(5); printf("I am the %d ID is %d .n", i + 1, getpid()); } else { pid_2 = wait(&status); if (-1 == pid_2) { perror("wait precess "); exit(1); } printf("Recovery of the %d process is is ID %d .n", i, pid_2); if (WIFEXITED(status)) { printf("Normal exit of process, Exit status : %d .n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("The program exits with abnormal signal, signal value : %d.n", WTERMSIG(status)); }

printf("I am is father.n"); }

//printf("hello from Recycle_child_process!n"); return 0;}我fork了⼀个⼦进程,并让它休眠5s。注意我的wait函数是在⽗进程分⽀中调⽤的,这⾥涉及到⼏个宏函数:WIFEXITED(status) 为⾮0 → 进程正常结束WEXITSTATUS(status) 如上宏为真,使⽤此宏 → 获取进程退出状态 (exit的参数)WIFSIGNALED(status) 为⾮0 → 进程异常终⽌WTERMSIG(status) 如上宏为真,使⽤此宏 → 取得使进程终⽌的那个信号的编号。这样,程序会输出:I am the 1 ID is 6024 .Recovery of the 1 process is is ID 6024 .Normal exit of process,Exit status:0 .I am is 应该是不会⼀样的。程序显⽰该⼦进程是正常退出的,返回值为0;我们可以改动这个返回值:⽤return 语句if (i < 1){ sleep(5); printf("I am the %d ID is %d .n", i + 1, getpid()); return 1314520;}那么程序的输出就应该是:I am the 1 ID is 6024 .Recovery of the 1 process is is ID 6024 .Normal exit of process,Exit status:1314520 .I am is father.那我们怎么让⼦进程异常退出?毕竟平常也很少遇到。我们可以⼈为的营造环境,段错误知道吧?浮点异常知道吧?不知道可以百度或⾕歌。我们来编写⼀个程序:#include int main(void){ int i = 5 / 0;//浮点异常 char *p = "love dandan"; p[2] = 69; return 0;}

编译并命名为。然后我们修改程序为:if (i < 1){ execl(" / home / lovedan / projects / Recycle_child_process / bin / x64 / Debug / ", "", NULL);//第⼀个参数⼀定是绝对路径。相信你知道execl函数 /*sleep(5); printf("I am the %d ID is %d .n", i + 1, getpid());*/}这时候,程序的输出。。。。输出结果我丢失了,也不想在去重新弄了。反正吧,他会输出⼦进程被成功回收,但是⼦进程是异常退出。提⽰浮点异常,value值是8(即:SIGFPE)。将in i=5/0;注释掉之后在编译它,重新运⾏另外⼀个程序输出结果⼜会不⼀样。会提⽰我们⼦进程因为段错误⽽退出。⼤概就这些吧,后⾯还有⼀个waitpid函数。后⾯在来介绍吧。

来更新⼀下:循环回收多个⼦进程:上⾯的⽰例是指创建回收⼀个⼦进程,若是我们创建多个,该如何回收呢?⽤循环!for (; i != 10; i++){ pid_1 = fork(); if (!pid_1) { break; }}if (i < 10){ sleep(i); printf("I am the %d ID is %d .n", i + 1, getpid());}else{ sleep(i); while (pid_2 = wait(&status) != -1)//循环回收进程 { printf("Recovery of the %d process is is ID %d .n", i, pid_2);

if (WIFEXITED(status)) { printf("Normal exit of process, Exit status : %d .n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("The program exits with abnormal signal, signal value : %d.n", WTERMSIG(status)); }

printf("I am is father.n"); }

if (-1 == pid_2) { perror("wait precess "); exit(1); }}我就只是贴了我修改的代码。其实变动很少,就是加个循环控制⽽已,这个程序的输出是:I am the 1 ID is 1225 .I am the 2 ID is 1226 .I am the 3 ID is 1227 .I am the 4 ID is 1228 .I am the 5 ID is 1229 .I am the 6 ID is 1230 .I am the 7 ID is 1231 .I am the 8 ID is 1232 .I am the 9 ID is 1233 .I am the 10 ID is 1234 .Recovery of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is ry of the 10 process is is ID 1 .Normal exit of process,Exit status:0 .I am is father.有没有发现回收的ID全为1?因为⼦进程先于⽗进程结束啊,是正常的结束,返回值为0;如果想要测试异常结束,请⾃⾏营造环境。

发布者:admin,转转请注明出处:http://www.yc00.com/web/1690955001a472269.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信