#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
是缓冲的,所以很可能不会看到其他行重叠。但是,如果直接使用write
来stdout
,则输出可能重叠。然而,在你的场景中,孩子们死得太快了,因为你正在阅读
从一个文件(可能需要一段时间才能返回),到下一个
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
,行可能重叠。