簡體   English   中英

為什么從管道讀取時read()不會返回零

[英]Why read() wont return zero when reading from pipe

我上課要交作業有問題。 我必須創建一個讀/寫程序,該程序將向其中讀取文本文件並將內容寫入新的文本文件。 關鍵是,我必須使用父/子進程和管道。 我必須將內容與一個孩子一起傳遞到管道中,並使用另一個孩子從管道中讀取數據並將其寫入新文件。

我有三個文件: parent.cread.cwrite.c 該程序在大多數情況下都能正常運行! 它甚至可以完美地將數據從一個文件傳輸到另一個文件。 我遇到的問題是write.c進程將永遠無法完成。 我認為這可能與管道讀取有關(不會返回0或EOF)。 這是我的源代碼:

父母

#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFF_SIZE 255

int main(int ac, char* av[]) 
{   
    if(ac <3)
    {
        printf("Please enter all required arguments!\n");   
        exit(0);    
    }

    int pfd[2];
    int pipeCreated;

    char readFile[50];
    char writePipe[20];

    pid_t child_pid_read;
    pid_t child_pid_write;

    pipeCreated = pipe(pfd);

    if(pipeCreated == -1)
    {
        printf("An error occurred when trying to create a pipe\n");
        exit(0);
    }

    strcpy(readFile, av[1]);
    sprintf(writePipe,"%d", pfd[1]);

    child_pid_read = fork();

    char writeFile[50];
    char readPipe[20];

    //Handling the read()
    switch(child_pid_read) 
    {
        //Error in case forfk() failed
        case -1:
            perror("fork failed");
            return 1;

            //Handle child processes
        case 0:
             if(close(pfd[0]) == -1)
             {
                 printf("An error occurred while closing the pipe\n");
                 exit(0);
             }
             if(execle("./read.out", "./read.out", readFile, writePipe, (char*)0, NULL) == -1)
             {
                 printf("Child: Error creating read.\n");
                 exit(0);
             }

        default:
            wait(&child_pid_read);

            strcpy(writeFile, av[2]);
            sprintf(readPipe,"%d", pfd[0]);

            child_pid_write = fork();
            break;
    }

    //Handling the write
    switch(child_pid_write) 
    {
        //Error in case fork() failed
        case -1:
            perror("fork failed");
            return 1;

        //Handle child processes
        case 0:
            if(close(pfd[1]) == -1)
            {
                printf("An error occurred while closing the pipe\n");
                exit(0);
            }

            if(execle("./write.out", "./write.out", writeFile, readPipe, (char*)0, NULL) == -1)
            {
                printf("Child: Error creating read.\n");
                exit(-1);
            }
            break;

        default:
            wait(&child_pid_write);
            break;
    }
    printf("Write completed!");
    return 0;
}

read.c:

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

#define BUFF_SIZE 16

int main(int ac, char* av[]) 
{   
    char buffer[BUFF_SIZE];
    int fd;
    int pid;

    if(ac > 1)
    {
        fd = open(av[1], O_RDONLY);
        if(fd == -1)
        {
            printf("error: Could Not Open File\n");
            exit(0);
        }

        pid = atoi(av[2]);

    }

    int num_read = 1;

    while(1)
    {
        num_read = read(fd, buffer, BUFF_SIZE);

        if(num_read == -1)
        {
            printf("Error reading file\n");
            exit(0);
        }

        if(num_read == 0)
        {
            break;
        }

        if(write(pid, buffer, num_read) != num_read)
        {
            printf("Error writing to pipe\n");
            break;
        }
    }
    close(fd);
    return 1;
}

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

#define BUFF_SIZE 1

int main(int ac, char* av[]) 
{
    char buffer[BUFF_SIZE];

        int fd = open(av[1], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);

        int pid = atoi(av[2]);

        int num_read = 1;

    while(1)
    {
            num_read = read(pid, buffer, BUFF_SIZE);

            printf("num_read: %d\n", num_read);

            if(num_read == -1)
            {
                printf("Error reading pipe\n");
                break;
            }

            if(write(fd, buffer, num_read) != num_read)
            {
                printf("Error writing to file\n");
                break;
            }

            if(num_read == EOF)
            {
                break;
            }
    }

        close(fd);
        return 1;
}

請查看我的代碼並提出更正建議。 我傳遞文本文件的名稱通過終端( ./parent.outoldFile.txtnewFile.txt )。

兩個問題:

  1. 直到wait()返回讀過程之后,您才需要分派寫過程。 如果讀取過程嘗試寫入的數據超出管道緩沖區的容量,它將阻塞並且永不退出。 您需要允許兩個進程同時運行以避免此死鎖。 它可以處理一個小的文件,但是如果文件大於4KB,它將掛起。
  2. 分叉寫進程后,父進程必須關閉pfd[0] 直到讀取端打開的所有進程都將其關閉,管道的讀取器才會獲得EOF。 它應該是:

     default: if(close(pfd[0]) == -1) { printf("An error occurred while closing the pipe\\n"); exit(0); } wait(&child_pid_write); break; 

您的孩子想讀取數據,為什么要關閉fd [0],從管道返回表示fd [0]用於讀取,fd [1]用於寫入。由於我無法添加評論,因此我必須發表評論這里....

暫無
暫無

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

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