我正在创建一个多进程程序.当我尝试使用for循环调用fork()时if(f == 0) break;.我得到了所需数量的子进程.
但是现在,我正在处理输入文件,并且最初不知道所需的进程数.这是我的代码中最小的可能示例.
FILE* file = fopen("sample_input.txt", "r");
while(fscanf(file, "%d", &order) == 1){
f = fork();
if(f == 0){
break;
}
}
Run Code Online (Sandbox Code Playgroud)
例如sample_input.txt:
5 2 8 1 4 2
Run Code Online (Sandbox Code Playgroud)
现在正在创建数千个子进程(我想要6,文件中的整数),可能是什么原因?它与文件指针有关吗?
编辑:我用控制台输出做了一些调试,子进程确实打破了循环.但是,父母一直在阅读一个小文件.如果我删除fork(),循环按预期执行6次.
编辑2:我有一个理论,我无法证明它也许你可以帮助我.可能是这样的情况:文件指针在进程之间共享,当子进程退出时,它关闭文件,当父进程再次尝试读取时,它只是从头开始(或其他一些奇怪的行为).可能是这样吗?
Jon*_*ler 10
当第一个进程读取第一个数字时,它实际上将整行读入内存.过程分叉.
子进程打破了循环; 接下来发生的事情没有指定,但可能会退出.父进程现在读取第二个数字并再次分叉.再一次,孩子退出,父母读取第三个数字,叉子等.
读取第六个数字并退出第六个子节点后,父节点将从文件中读取另一个缓冲区.在Linux上(或者更准确地说,使用GNU C库),您会得到一些奇怪的效果.请参阅为什么分叉我的进程会导致文件被无限读取?看到细节.但是,退出的子项将文件描述符的读取位置调整回开始,因此父级可以再次读取更多数据.
我对另一个问题的回答表明,如果子进程在退出之前关闭文件,则不会发生此行为.(无论如何不应该发生,但根据经验确实如此.)
GLIBC 错误23151 - 具有未关闭文件的分叉进程在退出之前执行lseek并且可能导致父I/O中的无限循环.
该错误创建于2019-05-08美国/太平洋地区,并于2018-05-09关闭为无效.给出的理由是:
请阅读 http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01,尤其是以下段落:
请注意,在a之后
fork(),存在两个句柄,其中之前存在一个句柄.[...]
请参阅为什么分叉我的进程会导致文件被无限读取?对此进行了广泛的讨论.