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


int main(int argc, char **argv) {
    FILE *file;
    file = fopen(argv[1], "r");
    char buf[600];
    char *pos;
    pid_t parent = fork();
    if(parent == 0) {
        while (fgets(buf, sizeof(buf), file)) {
            pid_t child = fork();
            if(child == 0) {
                /* is there a function I can put here so that it waits
                once the parent is exited to then run?*/
                printf("%s\n", buf);
                return(0);

            }

        }
        return(0);
    }
    wait(NULL);
    return(0);

}

这里的目标是同时打印出一行文件,并行。
例如:
给一个文件
a
b
c


$ gcc -Wall above.c
$ ./a.out file
a
c
b
$ ./a.out file
b
c
a

就像进程同时运行一样。我想如果有一个等待父退出的等待子句,然后开始运行这个孩子,我可以让它工作。如上面的评论所示。一旦父进程退出,所有进程都将按需要在打印语句开始。

最佳答案

如果你有:

int i = 10;
while (i > 0)
{
    pid_t child = fork();
    if(child == 0) {
        printf("i: %d\n", i--);
        exit(0);
    }
}

然后子进程同时运行。根据内核数量和操作系统调度程序,它们甚至可能同时运行。但是,printf是缓冲区,因此无法确定显示在屏幕上的行的顺序,并且在程序执行期间会有所不同。因为printf是缓冲的,所以很可能不会看到其他行重叠。但是,如果直接使用writestdout,则输出可能重叠。
然而,在你的场景中,孩子们死得太快了,因为你正在阅读
从一个文件(可能需要一段时间才能返回),到下一个fork执行时,
前一个孩子已经死了。但这并不能改变事实,如果
孩子们会跑得足够长,他们会同时跑,而且
无法确定屏幕上行的顺序。
编辑
正如Barmar在评论中指出的,write是原子的。我抬起头来
手册页和BUGS部分显示:
男2写
根据POSIX.1-2008/SUSv4第XSI 2.9.7节(“与常规文件操作的线程交互”):
当下列所有函数在常规文件或符号链接上操作时,它们应具有POSIX.1-2008中规定的原子效应:。。。
随后列出的api包括write()writev(2)。在线程之间的原子效应(以及
是文件偏移量的更新。但是,在3.14之前的Linux上,情况并非如此:如果两个进程共享
打开文件描述(请参见open(2))同时执行write()(或writev(2)),则I/O操作不是原子的
注意更新文件偏移量,结果是两个进程输出的数据块可能(错误地)重叠。
这个问题在Linux3.14中已经修复。
几年前我观察到这种行为
孩子们打印的东西,这就是为什么我写的write,行可能
重叠。

08-26 22:53
查看更多