[英]Parent process doesn't read from FIFO after child process death
所以。 我必須從命名管道讀取和寫入,我嘗試通過執行以下操作來完成此操作:父進程將命令寫入 FIFO,然后等待孩子死亡。 子進程讀取命令,並在另一個 fifo 中寫入一些內容。 父 Parent 從另一個 FIFO 讀取消息並打印結果。 我只能使用 fopen,因為在我的代碼中,我在其他地方使用 unistd 的 open,所以我沒有非阻塞標志。 我將在下面附上一個片段。 此外,如果我在子進程上使用“w”標志,代碼將完全凍結。 我知道 FIFO 是一種阻塞的通信方式,但我不明白為什么我的父母無法閱讀。 提前致謝。
int main()
{
FILE *fp1;
FILE* fp2;
unlink(FIFO_NAME1);
unlink(FIFO_NAME2);
//FIFO_NAME[1|2] is a macro containing the FIFO path
if(mkfifo(FIFO_NAME1, 0666) == -1)
{
printf("Something went wrong");
return -1;
}
if(mkfifo(FIFO_NAME2, 0666) == -1)
{
printf("Something went wrong");
return -1;
}
while(1)
{
char command[MAX_SIZE];
pid_t pid;
if((pid=fork()) !=0)
{
//parent
fgets(command, MAX_SIZE, stdin);
if((fp1= fopen(FIFO_NAME1, "w")) == NULL)
{
printf("Error");
}
fprintf(fp1, "%s", command);
fclose(fp1);
wait(SIGKILL);
//it never prints this or execute past the wait
printf("Here \n");
char response[MAX_SIZE];
if((fp2= fopen(FIFO_NAME2,"r"))==NULL)
perror("");
fgets(response, MAX_SIZE, fp2);
fclose(fp2);
//printf("%s",response);
}
else
{
//child
char msg[MAX_SIZE];
if((fp1 = fopen(FIFO_NAME1, "r")) == NULL)
{
printf("Error");
}
fgets(msg, MAX_SIZE, fp1);
fclose(fp1);
if((fp2= fopen(FIFO_NAME2, "w+")) == NULL)
{
printf("Error");
}
char buffer[MAX_SIZE];
strcpy(buffer,"TEST MESSAGE");
fprintf(fp2, "%s", buffer);
fclose(fp2);
fflush(stdout);
kill(getpid(), SIGKILL);
}
}
}
這里的基本問題是你不能半開 FIFO。 至少,除非您以非阻塞模式打開它進行閱讀,否則不能使用fopen()
。 通常,打開 FIFO 進行讀取會阻塞,直到也打開相同的 FIFO 進行寫入,反之亦然。
關於FIFO_NAME1
,您在這方面FIFO_NAME1
。 父母打開它進行寫作,孩子打開它進行閱讀。 一旦雙方都這樣做了,他們就會繼續。
但是隨后父調用wait()
(也有一個不正確的參數,但這是一個單獨的問題)。 直到它的一個子進程終止,父進程才會從那個wait
成功返回。 只有這樣它才會嘗試打開FIFO_NAME2
(用於讀取),但由於子進程已經終止,該 FIFO 不會被任何進程打開以供任何進程寫入,並且嘗試打開它會無限期地阻塞。
然后是孩子。 它成功地打開第二個 FIFO 只是因為您指定了模式"w+"
,這樣子項就可以同時滿足讀取器的要求和寫入器的要求。 然而,這是危險的,因為如果子進程實際上沒有從 FIFO 中消耗任何數據,那么它可能會通過嘗試向其寫入比內核一次願意緩沖更多的數據而死鎖。 此外,它無法實現您的通信目標,因為無法保證 FIFO 在停止為讀取或寫入而打開時會保留子節點寫入的數據。 確實,它可能不會。
您需要移動或刪除wait()
調用,如果您選擇前者,那么您需要檢查文檔以發現您應該傳遞什么樣的參數。 如果您願意相信子FIFO_NAME2
不會填充管道的緩沖區,那么您可以將等待移至父FIFO_NAME2
打開FIFO_NAME2
和嘗試讀取任何內容之前。 就其本身而言,子進程應該確保以只寫模式打開第二個 FIFO,以確保父進程和子進程在子進程開始寫入之前都打開該 FIFO。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.