Thread: using only one pipe for n processes

  1. #1
    Registered User
    Join Date
    Mar 2021
    Posts
    2

    using only one pipe for n processes

    I'm kinda confused on how i can only one pipe for n processes. Can you anyone please explain. Thanks in advance

  2. #2
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Writing is realatively eays - using write() to write data to pipes are guaranteed to be atomic only if less that PIPE_BUF bytes are written at a time.

    write

    Reads are a different.

    Because of this a "multiple writer, single reader" pipe is relatively simple to achieve as long as the data sent is short, but multiple readers is a harder problem hard to solve, requiring additional coordination between the readers.

  3. #3
    Registered User
    Join Date
    Mar 2021
    Posts
    2
    Can you show me an example like using fork to split into n processes and then connecting them using one pipe to show its correct working

  4. #4
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Here's two writers, one reader. You should be able to take it from here...

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    
    
    #define MESSAGES 1000000
    
    
    char message1[] = "Hello\n";
    char message2[] = "World\n";
    
    
    int main(int argc, char *argv[]) {
       int pipe_fd[2];
       // Create pipes
       if(pipe(pipe_fd) == -1) {
          printf("Unable to open pipe");
          return 0;
       }
    
    
       // First writer
       if(fork() == 0) {
          int len = strlen(message1);
          for(int i = 0; i < MESSAGES; i++) {
             write(pipe_fd[1], message1, len);
          }
          return 0;
       }
    
    
       // Second writer
       if(fork() == 0) {
          int len = strlen(message2);
          for(int i = 0; i < MESSAGES; i++) {
             write(pipe_fd[1], message2, len);
          }
          return 0;
       }
    
    
       // And here is the reader
       int bytes_left = strlen(message1)*MESSAGES+strlen(message2)*MESSAGES;
    
    
       while(bytes_left > 0) {
          char buff[1024];
          ssize_t to_read = sizeof(buff);
          if(to_read > bytes_left)
            to_read = bytes_left;
          ssize_t this_read = read(pipe_fd[0], buff, to_read);
          if(this_read == -1) {
             if(errno == EINTR)
                continue;
             break;
          }
    
    
          if(this_read <= 0) {
             break;
          } else {
             for(int i = 0; i < this_read; i++) {
                putchar(buff[i]);
             }
          }
          bytes_left -= this_read;
       }
    
    
       if(bytes_left == 0) {
          printf("Read of all messages complete\n");
       } else {
          printf("Read Error\n");
       }
       return 0;
    }

  5. #5
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Here's two writers, one reader. Expand as needed.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    
    
    #define MESSAGES 1000000
    
    
    char message1[] = "Hello\n";
    char message2[] = "World\n";
    
    
    int main(int argc, char *argv[]) {
       int pipe_fd[2];
       // Create pipes
       if(pipe(pipe_fd) == -1) {
          printf("Unable to open pipe");
          return 0;
       }
    
    
       // First writer
       if(fork() == 0) {
          int len = strlen(message1);
          for(int i = 0; i < MESSAGES; i++) {
             write(pipe_fd[1], message1, len);
          }
          return 0;
       }
    
    
       // Second writer
       if(fork() == 0) {
          int len = strlen(message2);
          for(int i = 0; i < MESSAGES; i++) {
             write(pipe_fd[1], message2, len);
          }
          return 0;
       }
    
    
       // And here is the reader
       int bytes_left = strlen(message1)*MESSAGES+strlen(message2)*MESSAGES;
    
    
       while(bytes_left > 0) {
          char buff[1024];
          ssize_t to_read = sizeof(buff);
          if(to_read > bytes_left)
            to_read = bytes_left;
          ssize_t this_read = read(pipe_fd[0], buff, to_read);
          if(this_read == -1) {
             if(errno == EINTR)
                continue;
             break;
          }
    
    
          if(this_read <= 0) {
             break;
          } else {
             for(int i = 0; i < this_read; i++) {
                putchar(buff[i]);
             }
          }
          bytes_left -= this_read;
       }
    
    
       if(bytes_left == 0) {
          printf("Read of all messages complete\n");
       } else {
          printf("Read Error\n");
       }
       return 0;
    }

  6. #6
    Registered User
    Join Date
    Mar 2021
    Posts
    3
    what are you trying to accomplish? why only one pipe?

    on pipes...

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    
    #define BYTES 64
    
    
    int close2(int a, int b)
    {
        return close(a) & close(b);
    }
    
    
    int main(void)
    {
        static char buff[BYTES];
    
    
        setlinebuf(stdout);
    
    
        struct { int read, write; } to_child, from_child; /* i like using a struct, but... */
    
    
        pipe((int *)&to_child);    /* ...could these casts ever cause problems? */
        pipe((int *)&from_child);  /* ...the memory layout is the same as int[2], correct? */
    
    
        if (!fork())
        {
            close2(to_child.write, from_child.read);
    
    
            write(from_child.write, "child says hi", 14); /* why i like the struct... easy to remember which end */
    
    
            read(to_child.read, buff, BYTES);
    
    
            printf("child received : %s\n", buff);
    
    
            _exit(0);
        }
    
    
        close2(to_child.read, from_child.write);
    
    
        read(from_child.read, buff, BYTES);
    
    
        printf("parent received : %s\n", buff);
    
    
        write(to_child.write, "parent says hi back", 20);
    
    
        wait(NULL);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating a Pipe between 2 processes
    By eZACKe in forum C Programming
    Replies: 3
    Last Post: 04-08-2012, 05:31 PM
  2. Pipe multiple programs using pipe() and c
    By HaitiBoy in forum C Programming
    Replies: 1
    Last Post: 12-07-2010, 05:19 PM
  3. Replies: 2
    Last Post: 12-06-2008, 02:17 PM
  4. Same pipe to multiple processes?
    By Ironic in forum C Programming
    Replies: 7
    Last Post: 10-25-2008, 10:10 AM
  5. Pipe problem, popen(), pipe().
    By apacz in forum C Programming
    Replies: 7
    Last Post: 06-08-2006, 12:55 AM

Tags for this Thread