gpt4 book ai didi

c - 为什么从管道读取时 read() 不会返回零

转载 作者:行者123 更新时间:2023-11-30 15:55:15 27 4
gpt4 key购买 nike

我的类作业有问题。我必须创建一个读/写程序,将文本文件读入其中并将内容写入新的文本文件。问题是,我必须使用父/子进程和管道。我必须使用一个子级将内容传递到管道中,并使用另一个子级从管道读取数据并将其写入新文件。

我有三个文件:parent.cread.cwrite.c。该程序在大多数情况下运行良好!它甚至可以完美地将数据从一个文件传输到另一个文件。我遇到的问题是 write.c 进程永远不会完成。我认为这可能与从管道读取数据有关(不会返回 0 或 EOF)。这是我的源代码:

父级.c

#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;
}
<小时/>

读取.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;
}
<小时/>

写.c

#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() 返回之前,您不会 fork 写入进程。如果读取进程尝试写入的数据多于管道缓冲区所能容纳的数据,它将阻塞并且永远不会退出。您需要允许两个进程同时运行以避免这种死锁。它可以处理小文件,但如果文件大于 4KB,它将挂起。
  2. fork 写入进程后,父进程必须关闭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;

关于c - 为什么从管道读取时 read() 不会返回零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12400091/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com