C++ 运行3个子进程

C++ 运行3个子进程,c++,linux,C++,Linux,我有三个子进程和一个父进程 我希望程序按照这个顺序运行[Child1然后child2然后child3然后parent] 我一直在尝试下面的代码,但它没有给我正确的顺序 代码: 我知道通过使用waitpid()函数可以解决这个问题,我认为我使用的waitpid()是错误的。尽管你评论“代码正在工作,但它给了我错误的执行顺序”,但整个事情仍然完全不正确,很明显你不理解其他人试图说的话,因此,我将在这里进行尝试 int main() { pid_t ch11; pid_t ch22;

我有三个子进程和一个父进程

我希望程序按照这个顺序运行[Child1然后child2然后child3然后parent]

我一直在尝试下面的代码,但它没有给我正确的顺序

代码:

我知道通过使用
waitpid()
函数可以解决这个问题,我认为我使用的
waitpid()
是错误的。

尽管你评论“代码正在工作,但它给了我错误的执行顺序”,但整个事情仍然完全不正确,很明显你不理解其他人试图说的话,因此,我将在这里进行尝试

int main()
{
    pid_t ch11;
    pid_t ch22;
    pid_t ch33;
这些变量的用途是什么

    int ch1 = fork();
你读过fork手册吗?它清楚地表明,当创建子进程时,它在子进程中返回0,在父进程中返回pid。它也可能失败,所以你应该检查一下

考虑到这一点

    int ch2 = fork();
孩子和父母都到达这条线。因此,以前创建的子也会分叉

    int ch3 = fork();
猜猜看

    if (ch1==0) //child1
    {    cout<<"this is child 1\nGoing from 1 to child 2 ...\n\n";
应该是你的出口

    }
    else if ( ch2==0)
    {    waitpid(ch11,0,0);
什么?ch11甚至还没有初始化,那么这应该实现什么呢? 您是否在编译代码时启用了警告

总的来说,我不知道您是想让子进程分叉,从而创建一个具有父子关系的for进程链,还是想要同一父进程的3个子进程。如果是后者,这是不好的,如果是前者,这是更错误的,因为你不能只是等待这样一个过程

[snip the rest]
最后,让我们谈谈这个问题

错误的执行顺序

什么

对于您流程的执行顺序没有任何保证。事实上,任意数量的它们都可以执行任意时间,并且在其他任何数量的它们有机会运行之前就被安排好多次


考虑到目前为止的情况,我倾向于猜测你要么误解了你的家庭作业,要么是非常“非常规”地处理它。无论哪种方式,我强烈建议您说明您的代码应该解决的实际问题。

这里有一个更好的代码检测版本;它在输出中包含PID,每个输出为一行

#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

int main()
{
    int ch1 = fork();
    int ch2 = fork();
    int ch3 = fork();

    if (ch1 == 0) // child1
    {
        cout << (int)getpid() << ": This is child 1 - Finished\n";
        exit(0);
    }
    else if (ch2 == 0)
    {
        waitpid(ch1, 0, 0);
        cout << (int)getpid() << ": This is child 2 - Finished\n";
        exit(0);
    }
    else if (ch3 == 0)
    {
        waitpid(ch2, 0, 0);
        cout << (int)getpid() << ": This is child 3 - Finished!\n";
        exit(0);
    }
    else
    {
        waitpid(ch3, 0, 0);
        cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
        exit(0);
    }
    return 0;
}

正如你所看到的,有一个过程认为自己是孩子3,两个过程认为自己是孩子2,而四个过程认为自己是孩子1,而一个认为自己是父母的过程。这与创建8个进程的无约束分叉一致

要仅生3个孩子,并依次等待每个孩子,您需要类似以下代码:

#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

void child(int n)
{
    flush(cout);        // No pending output
    int pid = fork();
    if (pid < 0)
        cerr << (int)getpid() << ": failed to fork\n";
    else if (pid == 0)
    {
        cout << (int)getpid() << ": This is child " << n << " - Finished\n";
        exit(0);
    }
    else
    {
        int corpse;
        int status;
        while ((corpse = wait(&status)) != -1)
            cout << (int)getpid() << ": PID " << corpse << " exited with status "
                 << status << "\n";
    }
}

int main()
{
    child(1);
    child(2);
    child(3);
    cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
    return 0;
}

“…很多错误…”对诊断问题没有多大帮助。请详细说明这些错误。顺便说一句,在上一次
fork()
之后,您当前有8个进程,而不仅仅是4个。@Jarod42。。。很抱歉,我没有注意到这个错误,我已经编辑了代码并编译了它,但它仍然给我upove错误+我现在怎么有8个进程而不仅仅是4个?第二个“fork()”也由第一个子进程执行。最后一个调用由父进程执行,第一个子进程由第一个“fork()”创建,还有由第二个“fork()”创建的两个子进程,因此,最后,您有8个进程。仍然有许多错误,因为您没有使用
fork()
的头文件,这是`#include,我建议您查看[fork手册页]()。此外,您还应该在fork中创建fork,这样子进程中的fork将从两个进程变成四个进程。这里没有文件系统检查(
fsck(8)
)。请保持东西干净整洁。使用
\u Exit()
表示标准I/O缓冲区未刷新,等等。使用
Exit()
表示标准I/O缓冲区未刷新。在这种情况下,我认为
exit()
\u exit()
好得多。他使用了'\n',因此刷新了相关的缓冲区。如果我们讨论的是一般情况,盲目使用exit()是危险的,因为安装了“谁知道”atexit处理程序[cerr和我很抱歉每个人,你们都是对的,我现在可以理解为什么我产生了8个进程而不仅仅是4个。
wait()
系统调用设置
status
来保持孩子的退出状态(但这里他们都返回0,这真的很无聊)。有很多问题涉及到细节(一个合适的SO搜索词可能是“[c]waitpid”)。
[snip the rest]
#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

int main()
{
    int ch1 = fork();
    int ch2 = fork();
    int ch3 = fork();

    if (ch1 == 0) // child1
    {
        cout << (int)getpid() << ": This is child 1 - Finished\n";
        exit(0);
    }
    else if (ch2 == 0)
    {
        waitpid(ch1, 0, 0);
        cout << (int)getpid() << ": This is child 2 - Finished\n";
        exit(0);
    }
    else if (ch3 == 0)
    {
        waitpid(ch2, 0, 0);
        cout << (int)getpid() << ": This is child 3 - Finished!\n";
        exit(0);
    }
    else
    {
        waitpid(ch3, 0, 0);
        cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
        exit(0);
    }
    return 0;
}
$ ./3kids
40287: This is child 3 - Finished!
40285: This is child 1 - Finished
40286: This is child 2 - Finished
40290: This is child 1 - Finished
40289: This is child 2 - Finished
40288: This is child 1 - Finished
40284: This is parent - waited for all children to finish!
40291: This is child 1 - Finished
$
#include <iostream>
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

void child(int n)
{
    flush(cout);        // No pending output
    int pid = fork();
    if (pid < 0)
        cerr << (int)getpid() << ": failed to fork\n";
    else if (pid == 0)
    {
        cout << (int)getpid() << ": This is child " << n << " - Finished\n";
        exit(0);
    }
    else
    {
        int corpse;
        int status;
        while ((corpse = wait(&status)) != -1)
            cout << (int)getpid() << ": PID " << corpse << " exited with status "
                 << status << "\n";
    }
}

int main()
{
    child(1);
    child(2);
    child(3);
    cout << (int)getpid() << ": This is parent - waited for all children to finish!\n";
    return 0;
}
$ ./3kids
40336: This is child 1 - Finished
40335: PID 40336 exited with status 0
40337: This is child 2 - Finished
40335: PID 40337 exited with status 0
40338: This is child 3 - Finished
40335: PID 40338 exited with status 0
40335: This is parent - waited for all children to finish!
$