简体   繁体   English

为什么我的waitpid()在进行后台进程后不等待孩子

[英]Why does my waitpid() not wait for child after making a background process

I wrote this simple program which endlessly asks the user for an input and then creates another process with fork() to execute "ls -la".我编写了这个简单的程序,它无休止地要求用户输入,然后用 fork() 创建另一个进程来执行“ls -la”。

When the user input was 0, the process is created as a background process.当用户输入为 0 时,该进程被创建为后台进程。 If the user input was anything else, the parent process waits for the child process to terminate.如果用户输入是其他内容,则父进程等待子进程终止。

In each iteration, zombie processes are terminated.在每次迭代中,僵尸进程都会终止。 This seems to work just fine这似乎工作得很好

The problem with this code is: When a background process is created, the parent process for any subsequent processes does not wait any more.这段代码的问题是:创建后台进程时,任何后续进程的父进程都不再等待。

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


void delete_zombies(void)
{
    pid_t kidpid;
    int status;

    while ((kidpid = waitpid(-1, &status, WNOHANG)) > 0)
    {
        printf("Child %ld terminated\n", kidpid);
    }
}

int main() {

    int runBGflag =0;

    while(1)
    {
        scanf("%d",&runBGflag); //get user input
        if (runBGflag==0) printf("making a child process and wait for it to finish\n");
        else printf("making a background process\n");
        pid_t pid;   //fork
        pid = fork();




        if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
        {
            int status;
            if (waitpid(-1, &status, 0) == pid && WIFEXITED(status))
            {
                printf("child dead. parent continues\n");
            }
        }

        if (pid == 0)  //Child process. Executes commands and prints error if something unexpected happened
        {
            execlp ("ls", "-la", NULL);
            printf ("exec: %s\n", strerror(errno));
            exit(1);
        }

        delete_zombies();
    }

}

I expect the output我期待 output

EG I would expect following output after input 010 EG 我希望在输入 010 之后跟随 output

0
making a child process and wait for it to finish
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp
child dead. parent continues
1
making a background process
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp
0
making a child process and wait for it to finish
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp
child dead. parent continues

However i only get但是我只得到

0
making a child process and wait for it to finish
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp
child dead. parent continues
1
making a background process
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp
0
making a child process and wait for it to finish
CMakeCache.txt  cmake_install.cmake  sigchild      Testing
CMakeFiles  Makefile         sigchild.cbp

You are waiting for any child processes in this part:您正在等待此部分中的任何子进程:

if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
{
    int status;
    if (waitpid(-1, &status, 0) == pid && WIFEXITED(status))
    {
        printf("child dead. parent continues\n");
    }
}

Therefore, the "background process" may corrected here instead of the new process.因此,这里可能会更正“后台进程”而不是新进程。 The "background process" should have different pid from the new process, so the message "child dead..." may not be printed. “后台进程”应该与新进程具有不同的 pid,因此可能不会打印消息“child dead...”。

This can be verified by inserting a debug-printing statement like this:这可以通过插入如下调试打印语句来验证:

if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
{
    int status;
    pid_t ret = waitpid(-1, &status, 0);
    printf("debug: expected %d, actual %d\n", (int)pid, (int)ret);
    if (ret == pid && WIFEXITED(status))
    {
        printf("child dead. parent continues\n");
    }
}

To avoid this, you should specify the process to wait via the first argument of waitpid() like this:为避免这种情况,您应该通过waitpid()的第一个参数指定要等待的进程,如下所示:

if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
{
    int status;
    if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
    {
        printf("child dead. parent continues\n");
    }
}

In the event that you run the child with the intention of waiting for it, you do not actually wait for that specific child, but rather for any child.如果您运行孩子的目的是等待它,您实际上并没有等待那个特定的孩子,而是等待任何孩子。 If there is a previously launched and unwaited-for child then that can be collected instead.如果有一个先前启动且未等待的孩子,则可以收集它。

You want something more like this:你想要更像这样的东西:

        if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
        {
            int status;
            if (waitpid(pid, &status, 0) == pid && WIFEXITED(status)) // CHANGED
            {
                printf("child dead. parent continues\n");
            }
        }

Note also that WIFEXITED(status) tests whether the process being reported on terminated normally .另请注意, WIFEXITED(status)测试报告的进程是否正常终止。 That does not include those that are killed by signals, which are nevertheless just as dead.这不包括那些被信号杀死的人,尽管如此,他们还是死了。 It also does not include those that have been stopped but not terminated -- those are not dead, but your program stops waiting for them anyway.它也不包括那些已经停止但没有终止的那些——那些没有死,但你的程序无论如何都会停止等待它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让我的父母等待,直到中间父母的中间父母、孩子和孩子使用 fork、wait 和 waitpid 完成该过程? - How do I make my parent wait, until a Intermediate parent, child and child of Intermediate parent finish the process using fork, wait, and waitpid? 子进程的waitpid不成功 - waitpid for child process not succeeding 我怎么知道我的子进程实际上是在调用waitpid()之后获得的? - How can I know that my child process is actually reaped after a call to waitpid()? 使用 `clone()` 创建子进程。 为什么 `wait()` 不等待它终止? - Created child process with `clone()`. Why does `wait()` not wait for it to terminate? 使用waitpid在后台运行进程? - Using waitpid to run process in background? 为什么waitpid()对于所有子进程仅返回1? - Why does waitpid() only return 1 for all child processes? 为什么我的信号处理程序不等待子进程? - why my signal handler wait no just child process? 孩子可以在C,Unix中执行waitpid()和wait()吗 - Can a child execute waitpid() and wait() in C, Unix wait()/ waitpid()返回1,而不是孩子的pid,如何修复? - wait()/waitpid() returns 1, not pid of child, how to fix that? 等待执行可执行脚本的子进程 - Waitpid for a child process that execv an unexecutable script
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM