【问题标题】:Reading from pipe more than once多次从管道中读取
【发布时间】:2014-05-04 14:17:22
【问题描述】:

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

我想将数据从我的父进程发送到我的子进程。

这就是我尝试的方式:

#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.

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

【问题讨论】:

  • 你不能有两个进程从同一个管道读取。也许有人可以告诉你如何做相当于 main |三通 > (child_a) > (child_b)
  • 我有一个从一个管道读取的进程。 child_a 不使用 atm。
  • @cup:您可以从单个管道中读取任意数量的进程(但最常见的情况是一个数量级)。当多个进程读取管道时发生的情况是,每个进程都获取一些数据,但写入管道的任何给定字节仅由一个进程读取,而不是由每个进程读取。
  • 另见Reading from pipe on signal sending。查看代码很快就会意识到这些问题是相关的。 OTOH,这不仅仅是另一个的复制品。
  • @JonathanLeffler 这就是我的意思,但我没有正确表达它。

标签: c process pipe


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 2021-10-13
    相关资源
    最近更新 更多