0

授業の期限が迫っている課題に問題があります。テキスト ファイルを読み取り、その内容を新しいテキスト ファイルに書き込む読み取り/書き込みプログラムを作成する必要があります。問題は、親/子プロセスとパイプを使用する必要があるということです。コンテンツを 1 つの子でパイプに渡し、別の子を使用してパイプからデータを読み取り、新しいファイルに書き込む必要があります。

parent.cread.cおよびの 3 つのファイルがありwrite.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;
}

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;
}

write.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.out端末 ( 、oldFile.txt、 )を介してテキスト ファイルの名前を渡していますnewFile.txt

4

2 に答える 2

1

2 つの問題:

  1. 読み取りプロセスが戻るまで、書き込みプロセスをフォークしていません。読み取りプロセスが、パイプ バッファーに収まるよりも多くのデータを書き込もうとすると、ブロックされて終了しません。このデッドロックを回避するには、両方のプロセスを同時に実行できるようにする必要があります。小さなファイルでも動作しますが、ファイルが 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;
    
于 2012-09-13T06:37:05.610 に答える
0

あなたの子供はデータを読みたいのですが、なぜあなたはfd [0]を閉じ、パイプから戻って、読み取り用にfd [0]、書き込み用にfd [1]を示します。コメントを追加できないので、コメントを投稿する必要がありますここ....

于 2012-09-13T05:51:31.323 に答える