我正在試驗一些用於shell實現的C代碼,發現fgets()在我分叉進程後返回重複行,我無法理解,我將不勝感激任何幫助。使用fgets讀取輸入將返回C中的重複行
我的問題是:分叉是否更改父進程中打開文件中的偏移量?這似乎發生在我的程序中。
從下面@Vadim波諾馬廖夫和我的理解答案: 與fgets()不是線程安全的(或嚴格來說,它是,但把一個進程導致標準輸入以某種方式被初始化,導致共享文件偏移的更改)。
的代碼是這樣的:
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;
}
我也有一個輸入文件臨時用一些隨機文本:
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;
}
謝謝!
能否請您編輯你的問題*顯示*實際(和預期)輸出(完整,複製粘貼爲文本)?還請包括一個實際的[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve),這是我們可以輕鬆地複製和測試自己的東西。 –
@Someprogrammerdude嗨,我添加了輸出。總之,我不希望看到重複的行被讀取。 –
父母和孩子正在共享相同的文件描述符,你期望進入關於標準輸入的分叉是什麼? –