c - fork输出不正确

标签 c fork

<分区>

考虑以下程序的输出:

int main()
{
    int ret;
    ret=fork();
    ret=fork();
    ret=fork();
    ret=fork();

    if(!ret)
            printf("one\n");
    else
            printf("two\n");
    return 0;
}

我得到的输出是:

two
one
two
two    

http://ideone.com/omgKm

AFAIT,输出应该是8 times one & 8 times two

其余的一个两个在哪里?

最佳答案

考虑这个替代代码,它可以更好地跟踪发生的事情:

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

int main(void)
{
    int ret1 = fork();
    int ret2 = fork();
    int ret3 = fork();
    int ret4 = fork();

    if (ret4 == 0)
        printf("one: (%d: %d, %d, %d, %d)\n", (int)getpid(), ret1, ret2, ret3, ret4);
    else
        printf("two: (%d: %d, %d, %d, %d)\n", (int)getpid(), ret1, ret2, ret3, ret4);
    return 0;
}

向我们展示此变体的输出,我们可以看到哪些有效,哪些失败。


在看到替代输出后,我在我的 Mac 上得到了这个(其中 Isis JL: 是我的提示,rmkmake 的替代实现):

Isis JL: rmk fb && ./fb
    /usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra fb.c -o fb  
two: (38068: 38069, 38070, 38071, 38072)
one: (38072: 38069, 38070, 38071, 0)
two: (38071: 38069, 38070, 0, 38075)
two: (38070: 38069, 0, 38074, 38077)
two: (38073: 0, 0, 38078, 38079)
two: (38069: 0, 38073, 38076, 38080)
one: (38075: 38069, 38070, 0, 0)
one: (38077: 38069, 0, 38074, 0)
Isis JL: two: (38074: 38069, 0, 0, 38081)
two: (38078: 0, 0, 0, 38082)
one: (38079: 0, 0, 38078, 0)
one: (38081: 38069, 0, 0, 0)
two: (38076: 0, 38073, 0, 38083)
one: (38080: 0, 38073, 38076, 0)
one: (38083: 0, 38073, 0, 0)
one: (38082: 0, 0, 0, 0)

Isis JL:

注意交错的提示——最后的空白行是我在输出完成后按回车键的地方。

假设:

ideone 上的输出在初始进程停止后未被捕获。

试试这个替代方案,它在退出之前等待 child 死亡:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    int ret1 = fork();
    int ret2 = fork();
    int ret3 = fork();
    int ret4 = fork();

    if (ret4 == 0)
        printf("one: (%d: %d, %d, %d, %d)\n", (int)getpid(), ret1, ret2, ret3, ret4);
    else
        printf("two: (%d: %d, %d, %d, %d)\n", (int)getpid(), ret1, ret2, ret3, ret4);
    while (wait(0) > 0)
        ;
    return 0;
}

再次在 Mac 上输出:

Isis JL: rmk fb && ./fb
    /usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra fb.c -o fb  
two: (38111: 38112, 38113, 38114, 38115)
one: (38115: 38112, 38113, 38114, 0)
two: (38114: 38112, 38113, 0, 38119)
two: (38113: 38112, 0, 38117, 38121)
two: (38117: 38112, 0, 0, 38123)
one: (38119: 38112, 38113, 0, 0)
two: (38118: 0, 38116, 0, 38124)
one: (38121: 38112, 0, 38117, 0)
one: (38125: 0, 0, 38122, 0)
two: (38116: 0, 0, 38122, 38125)
two: (38122: 0, 0, 0, 38126)
two: (38112: 0, 38116, 38118, 38120)
one: (38120: 0, 38116, 38118, 0)
one: (38123: 38112, 0, 0, 0)
one: (38124: 0, 38116, 0, 0)
one: (38126: 0, 0, 0, 0)
Isis JL:

假设证明

只要你能证明任何事... http://ideone.com/zFoLn ...

这显示了所有 16 行输出。问题一定是“过早终止”。

关于c - fork输出不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11523027/

相关文章:

C语言 : find out if string s2 exists in s1

git - 我可以将 git 上的 fork 项目更新为原始/主副本吗?

linux - 如果某个进程从setuid二进制叉开始,并且子进程放弃了特权,那么仍可以信任该子进程吗?

我可以调用带有 int 参数的长参数的函数吗?

c - 系统调用C程序中的循环

c++ - 到 system() 还是 fork()/exec()?

c - 用户输入未被识别,但如果最初设置了数字则程序可以运行

c - 在 C 中处理信号、管道和分支

c - 如何找到动态数组的大小

python - 计算Cython中两个地理代码之间的距离