【问题标题】:Why does this code fail? child not waiting为什么这段代码会失败?孩子不等
【发布时间】:2013-04-19 17:36:50
【问题描述】:

好的,所以我一直在努力学习掌握子进程并正确等待它们完成。我已经阅读了很多 Stack Overflow Q/A,但我似乎仍然无法按照我的意愿让它工作。我一直在阅读/搜索这本书(C++ Primer plus 6th ed.) - 我已经做了一些研究,但我仍然不能让它像我想要的那样等待。

所以我在 Stack Overflow 上查看了几件事以供参考:Checking the status of a child process in C++

这是我迄今为止尝试过的:

using namespace std;
int main() {
int status;
pid_t child;
child = fork();

if ( child > 0 ) {
    cout << "\nChild #1 is in charge\n";
    execlp("ls", "ls", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething wen't wrong in the forking process\n";
}

else {

}

child = fork();
if ( child > 0 ) {
    cout << "\nSecond child is in charge\n";
    execlp("locate", "locate", "etc", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething went wrong in the forking of second child!\n";
}

else {

}

现在这将显示Child #1 is in chargeSecond child is in charge 然后它将混合这两个命令(我看到一些ls 在定位etc 之间)。

我尝试的第二件事:

using namespace std;
int main() {
int status;
pid_t child;
pid_t ch_status = waitpid(child, &status, WNOHANG);

child = fork();
if ( child > 0 ) {
    cout << "\nChild is in charge\n";
    execlp("ls", "ls", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething wen't wrong in the forking process\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #1\n";
}

else {

}

child = fork();
if ( child == 0 ) {
    cout << "\nSecond child is in charge\n";
    execlp("locate", "locate", "etc", NULL);
}

else if ( child < 0 ) {
    cout << "\nSomething went wrong in the forking of second child!\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #1\n";
}

else {

}

child = fork();
if ( child > 0 ) {
    cout << "\nThird child is in charge!\n";
    execlp("echo", "echo", "herro", NULL);
}

else if ( child < 0 ) {
    cout << "\nForking of third child failed!\n";
}

if ( ch_status == 0 ) {

}

else if ( ch_status == -1 ) {
    cout << "\nERROR IN CHILD #2\n";
}

else {

}

return 0;
}

这更多基于我提供的链接,它产生的结果与我第一次测试运行的结果相同,除了它还会显示ERROR IN CHILD #1/2

这些命令无关紧要,我只是想不明白我在这里做错了什么......我也尝试将它们嵌套在 else { //start second fork here } 中,但我也无济于事。

根据阅读waitpid(2) 手册后的理解,我应该使用WNOHANGhttp://linux.die.net/man/2/waitpid

非常感谢任何建议/指针。

如果可能,请提交一个示例代码,说明您将如何完成正确的结果(execute command 1 -&gt; wait until done -&gt; execute command 2 -&gt; exit)

期待回复。

【问题讨论】:

    标签: c++ ubuntu exec parent-child waitpid


    【解决方案1】:

    你应该在你 fork 之后 在父级中调用 waitpid()。也就是说,它应该进入child &gt; 0 分支。

    该函数的目的是“等待子状态的变化”。但是,您是在生成孩子之前调用它。

    代码应如下所示:

    using namespace std;
    int main() {
    
    int status;
    pid_t child;
    
    child = fork();
    if ( child == 0 ) {
        cout << "\nChild is in charge" << endl;
        execlp("ls", "ls", NULL);
    } else if ( child < 0 ) {
        cout << "\nSomething wen't wrong in the forking process" << endl;
    } else {
        cout << "Parent waiting" << endl;
        pid_t ch_status = waitpid(child, &status, WNOHANG);
        if (ch_status == -1) {
          cout << "\nERROR IN CHILD #1" << endl;
        }
    }
    
    child = fork();
    //same procedure as above
    
    }
    

    【讨论】:

    • 我想我有点明白你的意思,你能不能给我提供一个小预览它应该/可以是什么样子?
    • @dusz 我已经扩展了答案。
    • 现在看看,第二个
    • 好吧,这次它工作得很好,但是当我像你在最后使用"\n"而不是&lt;&lt; endl一样运行它时,它会将内容放置在错误的位置。选择作为答案,考虑按照@david-schwartz 的建议更改为&lt;&lt; endl
    【解决方案2】:

    您错误地根据输出语句刷新的顺序来判断输出语句执行的顺序。虽然在执行相应的语句之前无法刷新输出,但您的代码中没有刷新调用。所以刷新可能会在很多之后发生。

    使用endl 而不是在行尾添加\nendl 操纵器包括一个刷新。

    【讨论】:

    • 感谢指出这一点,但它仍然没有正确等待,所以我一定做错了什么。 +1
    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多