如何解决完成子进程后,我的程序没有停止运行
我现在正在学习伙计,执行人员等,并且我有这段代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
pid_t childpid;
int status;
childpid=fork();
if (childpid== -1){
perror("Failed to fork\n");
exit(1);
}
if (childpid==0) {
printf("I am in child process with id = %lu\n",(long)getpid());
execvp(argv[1],&argv[1]);
perror("exec failure ");
exit(1);
}
else {
printf("I am in parent process with id = %lu\n",(long)getpid());
exit(1);
}
}
子进程运行正常,但是由于某些原因,该程序继续运行,没有执行任何操作。它从不打印“我在id = ....的子进程中”或“我在id = ...的父进程中”。就像从来没有去过父进程一样。你有什么想法吗?预先感谢
解决方法
根据我的最高评论...
您正在创建一个 zombie 进程。这是因为父进程没有等待子进程完成。
父进程将快速(相对)终止。因此,孩子失去了父母,成为了僵尸。僵尸将作为进程1的子级(例如systemd
或initd
)被内核重新定义。
要解决此问题,请在最后的wait(NULL);
之后添加printf
更新:
因此在这种情况下我需要始终放置wait(NULL)吗?
TL; DR是...是的!
这是大多数程序通常要执行的操作。
(例如)如果您是服务器程序(例如inetd
),则想要创建僵尸的次数之一。
服务器想要运行“分离”。也就是说,作为 init 进程的子级(例如systemd
,initd
等)。系统上只有一个 init 进程。
所有其他进程都是 init 的子进程,即使是间接的也是如此。例如,您程序的流程层次结构类似于:
init -> window_manager -> xterm -> bash -> your_program
无论如何,systemd
直接启动了这几天的大多数服务器程序。它检查一些配置文件,并根据这些配置选项启动操作。因此,现在,大多数服务器程序不必执行任何特殊操作。
但是,如果您正在测试自己的服务器,从命令行调用它,并希望它在后台运行[分离],则可以这样做:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
int opt_d;
int
main(int argc,char **argv)
{
char *cp;
pid_t childpid;
int status;
// skip over program name
--argc;
++argv;
for (; argc > 0; --argc,++argv) {
cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'd':
opt_d = 1;
break;
}
}
// detach into background
if (opt_d) {
childpid = fork();
if (childpid == -1) {
perror("Failed to detach\n");
exit(1);
}
// exit the parent -- child is now detached [and a zombie] and a child
// of the init process
if (childpid != 0)
exit(0);
}
childpid = fork();
if (childpid == -1) {
perror("Failed to fork\n");
exit(1);
}
if (childpid == 0) {
printf("I am in child process with id = %lu\n",(long) getpid());
execvp(*argv,argv);
perror("exec failure ");
exit(1);
}
printf("I am in parent process with id = %lu\n",(long) getpid());
wait(&status);
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。