簡體   English   中英

父進程無法讀取管道中子進程寫入的數據

[英]Parent process is unable to read data written by child process in pipe

在這個論壇中有許多與管道的讀寫有關的問題,但是我無法解決我的問題。 下面的代碼段執行以下操作:

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

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

注意:STEP 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;
}

我在此代碼中看到五個錯誤。 我將從最重要的到最不重要的列出它們。 我沒有嘗試修復任何錯誤,因此可能隱藏了更多錯誤。

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

  • 您沒有在檢查任何系統調用是否失敗。 每個系統調用后均應檢查故障。 如果確實失敗,則將失敗的完整描述打印到stderr ,包括失敗的系統調用的名稱,涉及的所有文件的名稱(如果有)和strerror(errno) ,然后以非零值退出程序( (失敗)退出代碼。 如果您這樣做了,那么您將自己發現,實際上,某些事情並不 “正常”。

  • 相關地,您沒有檢查孩子是否退出失敗。 父級應該執行waitpid(childpid, &status, 0)而不是wait(NULL) ,然后解碼退出狀態,並向stderr一條消息,以顯示WIFEXITED(status) && WEXITSTATUS(status) == 0 ,然后本身退出失敗。

  • 在父級中,您正在錯誤的地方呼叫wait 在讀取並處理了pipe_c所有數據之后,需要調用wait 否則,如果子進程完全填滿管道緩沖區,則程序將死鎖。 (此外,您需要從管道中讀取所有數據,而不僅僅是其中的前1000個字節。)

  • 在孩子中,您有一個緩沖區溢出。 您正在從文件讀取無限量的數據到buffer ,但是buffer具有固定的大小。 您應該根據需要使用mallocrealloc擴展,或者以不大於buffer大小的塊形式從文件復制到管道。

我通過在-f模式下在strace實用程序下運行程序來發現所有這些問題(因此它跟蹤了fork的兩面),並且輸入了一個大文件。 這是一種寶貴的調試技術,您應該自己嘗試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM