I'm kinda confused on how i can only one pipe for n processes. Can you anyone please explain. Thanks in advance
I'm kinda confused on how i can only one pipe for n processes. Can you anyone please explain. Thanks in advance
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.
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
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; }
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; }
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); }