Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么从管道读取时read()不返回零_C_Fork_Pipe - Fatal编程技术网

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

C 为什么从管道读取时read()不返回零,c,fork,pipe,C,Fork,Pipe,我的作业有问题,我要上课了。我必须创建一个读/写程序,将文本文件读入其中,并将内容写入新的文本文件。问题是,我必须使用父/子进程和管道。我必须将内容与一个子项一起传递到管道中,然后使用另一个子项从管道中读取数据并将其写入新文件 我有三个文件:parent.c,read.c和write.c。这个程序在大多数情况下运行良好!它甚至可以完美地将数据从一个文件传输到另一个文件。我遇到的问题是write.c进程永远不会完成。我认为这可能和管道中的读数有关(不会返回0或EOF)。以下是我的源代码: 父.c

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

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

父.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义BUFF_大小255
int main(int ac,char*av[])
{   
如果(ac 1)
{
fd=开路(仅限av[1];
如果(fd==-1)
{
printf(“错误:无法打开文件\n”);
出口(0);
}
pid=atoi(av[2]);
}
int num_read=1;
而(1)
{
num_read=读取(fd、缓冲区、缓冲区大小);
如果(num_read==-1)
{
printf(“读取文件时出错”);
出口(0);
}
如果(num_read==0)
{
打破
}
if(写入(pid、缓冲区、num\u读取)!=num\u读取)
{
printf(“写入管道时出错\n”);
打破
}
}
关闭(fd);
返回1;
}

#包括
#包括
#包括
#包括
#定义BUFF_大小1
int main(int ac,char*av[])
{
字符缓冲区[BUFF_SIZE];
int fd=开放(av[1],O|u WRONLY | O|u CREAT | O|u TRUNC,S|u IRUSR | S|u IWUSR);
int-pid=atoi(av[2]);
int num_read=1;
而(1)
{
num_read=read(pid、缓冲区、BUFF_大小);
printf(“num\u read:%d\n”,num\u read);
如果(num_read==-1)
{
printf(“读取管道时出错”);
打破
}
if(写入(fd、缓冲区、num\u读取)!=num\u读取)
{
printf(“写入文件时出错\n”);
打破
}
如果(num_read==EOF)
{
打破
}
}
关闭(fd);
返回1;
}


请查看我的代码并提出更正建议。我正在通过终端传入文本文件的名称(
/parent.out
oldFile.txt
newFile.txt
)。

您的孩子想要读取数据,为什么要关闭fd[0],从管道返回,指示fd[0]用于读取,fd[1]用于写入。因为我无法添加注释,我必须在这里发表评论….

有两个问题:

  • 在等待读取进程返回后,才开始分叉写入进程。如果读取进程试图写入的数据超过管道缓冲区的容量,它将阻塞并且永远不会退出。您需要允许两个进程同时运行以避免此死锁。它将使用一个小文件,但如果文件大于4KB,它将挂起
  • 分叉写入进程后,父进程必须关闭
    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;
    

  • 为了将来的参考,请阅读。非常感谢!这修复了我的程序,它可以在不挂起read()的情况下完美工作!你刚刚帮我省了一笔账,这项作业今晚就要交了,我从周一开始就一直在做。不过还是谢谢你!谢谢你的帮助。直到Barmar发布了他的答案,我才理解你的帖子,但同样感谢你!
    #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;
    }
    
    default:
        if(close(pfd[0]) == -1)
         {
             printf("An error occurred while closing the pipe\n");
             exit(0);
         }
        wait(&child_pid_write);
        break;