不止一次从管道读取

时间:2014-05-04 14:17:22

标签: c process pipe

我有一个父进程和一个子进程。

我想将父母的数据发送到我的孩子proc。

这是我尝试的方式:

#include<stdio.h>
#include<string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h> 
#include <signal.h>



//Handler - Exiting a process
void sigHandler(int signumber){
    printf("SIGQUIT catched.\n");
    exit(3);
}

void writeToPipe(int myData, int *pipe){

    close(pipe[0]);
    write(pipe[1], &myData,sizeof(myData));
    close(pipe[1]); 

}

int readFromPipe(int *pipe){

    int myData;

    close(pipe[1]);  
    read(pipe[0],&myData,sizeof(myData)); 
    close(pipe[0]); 

    return myData;
}

int main(){    

   int *pipefd = (int *)malloc(sizeof(int)*2);

    //Pipe Error handling
    if (pipe(pipefd) == -1){
          perror("Error on pipe init.");
           exit(EXIT_FAILURE);
     }


fflush(stdout);

char option=-1;

pid_t child_a;
pid_t child_b;

child_a = fork();

//A Child Proc which is not used atm, it will be
if (child_a == 0) {

    signal(SIGQUIT ,sigHandler); 

    while(1) {
      //idle    
        sleep(2);
        printf("child_a iddle work\n");
    }

} 

    //Child B Proc for reading form the PIPE
    else {

    child_b = fork();

    if (child_b == 0) {

        signal(SIGQUIT ,sigHandler); 

        while(1) {
        //idle
            sleep(2);
            printf("child_b iddle work\n");

            //So lets read from pipe
            int ret = readFromPipe(pipefd);
            printf("Read from pipe: %d\n", ret);

        }

    } 
    //Parent Proc for writing to a pipe 
    else {

            //MENU WHILE
            while(option!=0){

                scanf("%d", &option);
                printf("input was: %d\n", option);
                writeToPipe(option, pipefd);

            }

        }//End of Menu while

        //Exiting child prcoesses then exiting parent prcoess
        if(option==0){

            int status_a, status_b;

            waitpid(child_b, &status_b, WNOHANG|WUNTRACED);
            waitpid(child_a, &status_a, WNOHANG|WUNTRACED);

            kill(child_b,SIGQUIT); 
            kill(child_a,SIGQUIT); 

        }

    }

    return 1;

} 

输出中出现错误:

child_a iddle work
child_b iddle work
child_a iddle work
4
input was: 4
Read from pipe: 4   ///Wow its cool i got read nicely from the pipe with my child proc
child_a iddle work
child_b iddle work
Read from pipe: -1438072844    ///Okay.. so why is it junk? but lets go ahead with an input again
child_a iddle work
child_b iddle work
Read from pipe: -1438072844
child_a iddle work
1
input was: 1                 //Input again, it is 1
child_b iddle work
Read from pipe: -1438072844     //Read from pipe remains the same junk, and not 1, why?
child_a iddle work
child_b iddle work
Read from pipe: -1438072844
child_a iddle work
3
input was: 3                       //Same here with 3
child_b iddle work
Read from pipe: -1438072844
child_a iddle work
0
input was: 0                     //I exit with 0, that is okay.
SIGQUIT catched.
SIGQUIT catched.

我搜索了很多但是找不到解决方案,我只发现只有一个数据在管道中发送的例子而且不多。

1 个答案:

答案 0 :(得分:2)

因为readFromPipe和writeToPipe方法每次调用时都会关闭管道读写端的文件描述符。从那些方法中取出那些语句,你应该停止得到错误的输出(我假设是由close(),read()或write()的未被捕获的错误触发的,因为他们试图对已经关闭的文件描述符进行操作)。

要考虑的另一件事是关闭child_a中管道两端的管道fd,因为如果父不需要使用相同的管道写入child_a以及关闭管道的末端,则额外的引用是无用的。 child_b和parent不需要访问权限(例如,父级不需要读访问权限,子级不需要写访问权)