two children reading from a pipe

2019-06-05 14:29发布

问题:

Here's what I'd like to do:

I've tried to make a program that creates parent with two children, parent creates unnamed pipe, writes into it and the children are supposed to read from it (per 1 byte) and then output the results in two different terminal windows. What I do not know is how to synchronise them.

I get something like this in one terminal window: Nejke aa and in the second: adt I want: Nejake data

I tried searching on the internet, but I'm asking anyway. Any help is greatly appreciated.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

/* declare our procedures */
void runchild1(int pfd[]);
void runchild2(int pfd[]);

/* some data to write and read from pipe */
const char some_data[] =  "Nejake data" ;




int main(int argc, char **argv)
{
int pid, status;                //PID for debugging
int fd[2];                      //file descriptors for the          pipe

/* let create some pipe */
pipe(fd);   

/* supposed to run two children of the process */
runchild1(fd);
runchild2(fd);

/* this is important! close both file descriptors on the pipe */
close(fd[0]); close(fd[1]);     

/* pick up all the dead children */
while ((pid = wait(&status)) != -1) 
    fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status));
exit(0);
}



void runchild1(int pfd[])   /* run the first child */
{
int pid;                /* you may want to print it for debugging */
int data_processed;     /* store data */
int des;                /* descriptor for open files  */
char buffer;            /* buffer for reading byte of data  */

switch (pid = fork()) {

case 0:                 /* child reads from the pipe */

    close(pfd[1]);      /* this process don't need the other end */
    while ((data_processed = read(pfd[0],&buffer,1)) > 0) {

        printf("Proces %d, data citane po bajte: %c\n",getpid(),buffer);
        des = open("/dev/ttys001",O_RDWR);
        write(des, &buffer,1);          
    }               
    exit(0);

default: /* parent writes to the pipe  */       

    /* write some data for children to read */
    data_processed = write(pfd[1], some_data, strlen(some_data));
    printf("Zapis %d bytov cez nepomenovanu ruru:\n", data_processed);
    printf("Zapisane: %s\n",some_data);
    printf("Som rodic dvoch deti: %d\n",getpid());

    break;

case -1:
    perror("fork");
    exit(1);
}
}


void runchild2(int pfd[])   /* run the second child */
{
int pid;
int data_processed;
int des;
char buffer;

switch (pid = fork()) {

case 0:                 /* child */

    close(pfd[1]);      /* this process doesn't need the other end */
    while ((data_processed = read(pfd[0],&buffer,1)) > 0) {

        printf("Proces %d, data citane po bajte: %c\n",getpid(),buffer);
        des = open("/dev/ttys002",O_RDWR);
        write(des, &buffer,1);          
    }
    exit(0);        


default: /* parent does nothing */
    break;

case -1:
    perror("fork");
    exit(1);
}
}

回答1:

If the two children both need to see the same data, you'll need two pipes, one per child, and the parent must write each message twice, once on each pipe.

Alternatively, you could run the tee command with process substitution, or you can look up (try looking up) the program pee (process/pipe variant of tee) — or you can follow links from this Stack Overflow answer. Your program will have one pipe, but the children will each end up with their own pipe.



回答2:

Unix pipe is FIFO. One input, one output. Nothing like two outputs from one pipe. Your cheats are: System V IPC keyword and ipcs command.



标签: c unix pipe