2017-09-24 117 views
0

在此論壇中有許多與讀寫管道有關的問題,但我無法解決我的問題。 下面的代碼片段,並以下的事情:父進程無法讀取管道中的子進程寫入的數據

  1. 通過命令行參數的文件名是通過pipe_p傳遞給子進程
  2. 子進程打開指定的文件,並將它的內容pipe_c父進程閱讀並在屏幕上顯示。

一切工作正常,但父進程無法從管道讀取數據(因爲它不打印任何東西)。 我觀察到數據被成功寫入子進程,因爲我能夠通過管道在子進程塊中打印內容,但不能在父進程中打印內容。

注意:步驟4不起作用

任何人都請幫助我。

代碼:

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, char **argv){ 

    int pipe_p[2], pipe_c[2]; 
    int childpid, c, k = 0; 
    char buffer[1000] = {0}; 
    FILE *file; 

    pipe(pipe_p); 
    pipe(pipe_c); 

    childpid = fork(); 

    if(childpid){ 
     //parent process block 
     //STEP 1 ------- 
     close(pipe_p[0]); //closing reading side of pipe 
     write(pipe_p[1], argv[1], strlen(argv[1])); 
     close(pipe_p[1]); 
     //-------------- 
     wait(NULL); 
     //-------------- 
     //printf("%s\n", "Its working"); 
     //STEP 4 ------- 
     close(pipe_c[1]); 
     read(pipe_c[0], buffer, sizeof(buffer)); 
     close(pipe_c[0]); 
     printf("%s\n", buffer); 
     //-------------- 
    } 
    else{ 
     //child process block 
     //sleep(1); 
     //STEP 2 ------- 
     close(pipe_p[1]); 
     read(pipe_p[0], buffer, sizeof(buffer)); 
     close(pipe_p[0]); 
     //printf("%s\n", buffer); 
     //-------------- 

     //STEP 3 ------- 
     file = fopen(buffer, "r"); 
     while((c = getc(file)) != EOF){ 
      buffer[k++] = c; 
     } 
     buffer[k] = 0; 
     //printf("%s", buffer); 
     close(pipe_c[0]); 
     write(pipe_c[1], buffer, strlen(buffer)); 
     close(pipe_c[1]); 
     //-------------- 
    } 

    return 0; 
} 

回答

1

我看到在這個五級典的錯誤。我將把它們從最不重要的列表中列出。我沒有嘗試修復任何錯誤,所以可能會有更多隱藏在這些錯誤之後的東西。

  • 您忘記了包括sys/wait.h。編譯器應該抱怨wait的隱式聲明。 (如果您的編譯器沒有提出任何投訴,請打開所有警告。)

  • 您不檢查是否有任何系統調用失敗。 每個系統調用後都應該檢查失敗。如果發生故障,請打印至stderr有關故障的完整說明,包括失敗的系統調用名稱,涉及的所有文件的名稱(如果有)以及strerror(errno),然後用非零(不成功)退出程序退出碼。如果你已經這樣做了,那麼你會發現,事實上,某些事情是而不是「正常工作」。

  • 相關地,您不檢查孩子是否退出失敗。而不是wait(NULL),父應該做waitpid(childpid, &status, 0),然後解碼退出狀態並打印一條消息到stderr以外的任何東西WIFEXITED(status) && WEXITSTATUS(status) == 0,然後退出本身失敗。

  • 在父項中,您在錯誤位置調用wait。您需要撥打wait後您已經閱讀並處理了所有pipe_c的數據。否則,如果子進程完全填滿管道緩衝區,程序將會死鎖。 (另外,你需要從管道中讀取數據的所有,而不只是第1000個字節的吧。)

  • 在孩子,你有一個緩衝區溢出。您正在從文件讀取無限量的數據到buffer,但buffer有固定的大小。您應該使用mallocrealloc根據需要進行放大,或者以不大於buffer的大小將文件複製到管道中。

我的下strace工具運行的程序,在-f模式(所以它追溯了叉的兩側),從一個大的文件輸入發現所有這些問題。這是一個有價值的調試技術,您應該自己嘗試。

+0

感謝您的建議@zwol。我沒有得到你的第四點,在這裏我讓父進程等到子進程完成填充緩衝區(這是成功完成的,你可以通過取消printf部分的註釋來查看其他部分)。但是在返回到父上下文之後,如果我在其他部分中複製了STEP 4,則不會讀取在子進程中讀取的數據。 –

+0

好的,我會檢查你的編輯。如果你能使代碼工作,那將是非常好的。謝謝 –

+0

@ChanchalRoshan修復孩子的緩衝區溢出,然後使用一個_large_測試文件(至少32KB),你應該看到從等待過早的死鎖。現在,死鎖被緩衝區溢出所掩蓋,這使得孩子在填充管道緩衝區之前崩潰。 – zwol

相關問題