2

Linux パイプの仕組みを知りたい! 親プロセスと子プロセスの間でパイプを使用して文字列を通信する、小さくて簡単なプログラムを作成しました。しかし、このプログラムは原因が分からないデッドロックを引き起こします。

コードは次のとおりです。

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

#define SIZE 100  

int
main(int argc, char *argv[])
{
    int pfd[2];
    int read_pipe=0, write_pipe=0; 
    pid_t cpid;
    char buf[SIZE]; 

    /* PIPE ***************************************
     * pipe() creates a pair of file descriptors, *
     * pointing to a pipe inode, and places them  *
     * in the array pointed to by filedes.    *
     * filedes[0] is for reading,         *
     * filedes[1] is for writing          *
     **********************************************/

    if (pipe(pfd) == -1) { 
        perror("pipe"); 
        exit(EXIT_FAILURE);
    }

    read_pipe=pfd[0]; 
    write_pipe=pfd[1]; 

    cpid = fork();
    if (cpid == -1) { 
        perror("fork"); 
        exit(EXIT_FAILURE);
    }


    if (cpid == 0) {    /* Child reads from pipe */

    char * hello = "I am a child process\n"; 
    sleep(1);  
    // wait until there is some data in the pipe
        while (read(read_pipe, buf, SIZE) > 0);
    printf("Parent process has written : %s\n", buf);
    write(write_pipe, hello, strlen(hello)); 
    close(write_pipe);
    close(read_pipe);
        _exit(EXIT_SUCCESS);
    } else {                /* Parent writes argv[1] to pipe */

    char * hello = "I am a parent process\n";
    write(write_pipe, hello, strlen(hello));
    while (read(read_pipe, buf, SIZE) > 0); 
printf("Child process has written : %s\n", buf);

    close(write_pipe);       
    close(read_pipe);

    wait(NULL);             /* Wait for child */
    exit(EXIT_SUCCESS);
    }
}
4

2 に答える 2

0

おそらく、あなたの printf() 出力のいずれかが表示されているかどうかを知ることができますか? いずれにしても、親と子の間で双方向の通信を確立したい場合は、2 つのパイプを使用する必要があります。1 つは親から子へのデータの書き込み用で、もう 1 つは子から親への書き込み用です。さらに、読み取りループは危険な場合があります。データが 2 つ以上のチャンクに含まれる場合、2 番目の read() が最初の部分を上書きします (ローカル パイプで発生するのを見たことがありませんが、たとえばソケットで発生します)。もちろん、yout は read() の後で自動的に null で終了するわけではないため、"%s" で int を出力するだけでも問題が発生する可能性があります。試してみるためのアイデアが得られることを願っています。

于 2013-06-10T11:56:49.713 に答える