【问题标题】:fork(), runs always the parent first and then the childfork(),总是先运行父进程,然后是子进程
【发布时间】:2016-02-09 16:34:54
【问题描述】:

我正在了解fork(),但我的 ubuntu 出现了问题。我正在运行此代码:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
printf("--beginning of program\n");

int counter = 0;
pid_t pid = fork();

if (pid == 0)
{
    // child process
    int i = 0;
    for (; i < 5; ++i)
    {
        printf("child process: counter=%d\n", ++counter);
    }
}
else if (pid > 0)
{
    // parent process
    int j = 0;
    for (; j < 5; ++j)
    {
        printf("parent process: counter=%d\n", ++counter);
    }
}
else
{
    // fork failed
    printf("fork() failed!\n");
    return 1;
}

printf("--end of program--\n");

return 0;
} 

我知道父母和孩子应该不按特定顺序运行他们的代码,所以代码应该返回如下内容:

-beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
child process: counter=1
parent process: counter=4
child process: counter=2
parent process: counter=5
child process: counter=3
child process: counter=4
child process: counter=5
--end of program--

但是每次我运行程序时,它们似乎都以相同的顺序运行。这是我每次运行这个程序时得到的结果:

user@user-VirtualBox:~/Documents/S-O$ ./sample
--beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
parent process: counter=4
parent process: counter=5
--end of program--
user@user-VirtualBox:~/Documents/S-O$
child process: counter=1
child process: counter=2
child process: counter=3
child process: counter=4
child process: counter=5
--end of program--

似乎父母先完成,然后孩子开始。但我想那不是真的。请注意,第二个 shell 提示符是由程序本身打开的。对可能发生的事情有任何想法吗?

编辑:

如果我输入sleep(1),它就可以正常工作。我仍然认为毫不拖延地,它不应该总是具有相同的执行顺序。即使数到 100 也一样

【问题讨论】:

  • 当您使用较大的数字时会发生什么?在每个循环中都在那里睡觉,看看会发生什么。
  • 你试过数 > 5 吗?
  • 当我使用更大的数字时,它会做同样的事情。
  • 我怀疑您看到的序列化是基于标准输出的缓冲性质以及现代计算机数到五的速度。我采用了这段代码并没有缓冲标准输出,并将循环限制从 5 提高到 10K。然后它开始表现出来自子进程和父进程的一些 IO 交错。
  • @tripleee 我的父子计数都达到了 10000,并将标准输出从行缓冲修改为无缓冲setvbuf(stdout,NULL,_IONBF,0);,并且孩子在 200 左右开始交错(在 2014 年中期 MBP 为 2.mumble赫兹)。有趣的是,删除 setvbuf 导致父子序列再次序列化。

标签: unix fork


【解决方案1】:

是的,父母和孩子以几乎不可预测的顺序运行他们的代码(请记住,没有随机性),但是您的调度程序可能会在分叉后选择先安排父母,然后再安排孩子。由于两者都有一个非常小的代码,父级能够运行它的所有代码,然后是子级。要进行其他实验,您必须在两个进程中分叉后做更长的时间(例如,您将能够看到不同的输出交错)。

提示不是由您的代码产生的,而是它的效果。当父进程死亡时,运行它的 shell 会重新获得控制权并提示您输入另一个命令,同时子进程正在工作并污染您的终端。孩子成了孤儿进程。为防止这种情况发生,您必须通过调用...wait() 告诉父级等待其子级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 2012-09-14
    • 1970-01-01
    相关资源
    最近更新 更多