我的问题是:fork进程是否会改变父进程中任何打开文件的偏移量?这似乎发生在我的程序中。
根据下面@Vadim Ponomarev和我的理解: fgets()不是线程安全的(或者严格来说,它是线程安全的,但fork进程会以某种方式初始化stdin,导致共享文件偏移量发生变化)。
代码如下:
int main() {
char buf[200];
int r;
pid_t pid = 0;
while(getcmd(buf, 200, pid) >= 0) {
fprintf(stderr, "current pid: %d\n", getpid());
pid = fork();
// Without forking the fgets() reads all lines normally
if(pid == 0)
exit(0);
wait(&r);
}
return 0;
}
getcmd()函数只是一个封装:
int
getcmd(char *buf, int nbuf, pid_t pid)
{
memset(buf, 0, nbuf);
if (fgets(buf, nbuf, stdin) == NULL) {
fprintf(stderr, "EOF !!!\n");
return -1;
}
fprintf(stderr, "pid: %d -- getcmd buf ======= --> %s\n", getpid(), buf);
return 0;
}
我也有一个输入文件temp,里面包含一些随机的文本:
line 1
line 2
line 3
编译后,我运行a.out < temp,输出显示打印了6行内容,通常会有一些重复的行。但是如果我删除这行:
pid = fork()
...
然后输出就正常了(逐行显示所有行,这意味着fgets()被调用了3次)。
有任何想法是什么出了问题吗?
输出结果(这就是得到的):
pid: 10361 -- getcmd buf ======= --> line1
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
EOF !!!
我希望您能看到这个:
并且我期待着看到这个:
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line1
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
EOF
可供参考的可编译版本:
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
#include <zconf.h>
#include <unistd.h>
#include <memory.h>
int
getcmd(char *buf, int nbuf, pid_t pid)
{
memset(buf, 0, nbuf);
if (fgets(buf, nbuf, stdin) == NULL) {
fprintf(stderr, "EOF !!!\n");
return -1;
}
fprintf(stderr, "pid: %d -- getcmd buf ======= --> %s\n", getpid(), buf);
return 0;
}
int main() {
char buf[200];
int r;
pid_t pid = 0;
while(getcmd(buf, 200, pid) >= 0) {
fprintf(stderr, "current pid: %d\n", getpid());
pid = fork();
// Without forking the fgets() reads all lines normally
if(pid == 0)
exit(0);
wait(&r);
}
return 0;
}
谢谢!
exit
的调用。 - Jean-Baptiste Yunès