Last active
March 16, 2025 18:21
-
-
Save DocBohn/627c40a63a091e7bfc80040b53e10792 to your computer and use it in GitHub Desktop.
Demonstration of using a pipe to communicate between processes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
void fork_and_pipe(int *process, int *writing_fd, int *reading_fd0, int *reading_fd1, int *reading_fd2, int pipe_fd[4][2]); | |
void pipe_demo() { | |
int pipe_fd[4][2]; | |
int process; | |
int writing_fd, reading_fd0, reading_fd1, reading_fd2; | |
int const size_of_buffer = 256; | |
char buffer[size_of_buffer]; | |
int integer_buffer[1]; | |
fork_and_pipe(&process, &writing_fd, &reading_fd0, &reading_fd1, &reading_fd2, pipe_fd); | |
switch (process) { | |
case 0: | |
printf("Process 0 is going to sleep...\n"); | |
sleep(1); | |
printf("Process 0 sending a message to process 1...\n"); | |
write(writing_fd, "go!", 4); | |
printf("Process 0 is waiting for process 1...\n"); | |
read(reading_fd0, buffer, size_of_buffer); | |
printf("Process 0 received a message from process1: %s\n", buffer); | |
break; | |
case 1: | |
printf("Process 1 is waiting for process 0...\n"); | |
read(reading_fd0, NULL, size_of_buffer); // we don't care what was written | |
printf("Process 1 received a message from process 0.\n"); | |
read(reading_fd1, integer_buffer, sizeof(int)); | |
int value1 = integer_buffer[0]; | |
printf("Process 1 received %d from process 2.\n", value1); | |
read(reading_fd2, integer_buffer, sizeof(int)); | |
int value2 = integer_buffer[0]; | |
printf("Process 1 received %d from process 3.\n", value2); | |
sprintf(buffer, "%d + %d = %d", value1, value2, value1 + value2); | |
printf("Process 1 sending a message to process 0...\n"); | |
write(writing_fd, buffer, strlen(buffer) + 1); | |
break; | |
case 2: | |
integer_buffer[0] = 42; | |
write(writing_fd, integer_buffer, sizeof(int)); | |
break; | |
case 3: | |
integer_buffer[0] = 73; | |
write(writing_fd, integer_buffer, sizeof(int)); | |
break; | |
default: | |
printf("Process %d reached unreachable code; claims to be the %dth process.\n", getpid(), process); | |
exit(-1); | |
} | |
// files should close when the process terminates, but we'll practice good hygiene anyway | |
for (int i = 0; i < 4; i++) | |
for (int j = 0; j < 2; j++) | |
close(pipe_fd[i][j]); | |
} | |
void fork_and_pipe(int *process, int *writing_fd, int *reading_fd0, int *reading_fd1, int *reading_fd2, int pipe_fd[4][2]) { | |
for (int i = 0; i < 4; i++) { | |
pipe(pipe_fd[i]); | |
} | |
*process = 0; | |
if (fork() == 0) { | |
*process += 1; | |
} | |
if (fork() == 0) { | |
*process += 2; | |
} | |
switch (*process) { | |
case 0: | |
*reading_fd0 = pipe_fd[1][0]; | |
break; | |
case 1: | |
*reading_fd0 = pipe_fd[0][0]; | |
*reading_fd1 = pipe_fd[2][0]; | |
*reading_fd2 = pipe_fd[3][0]; | |
break; | |
case 2: | |
case 3: | |
// processes 2 & 3 won't read in this example | |
break; | |
default: | |
printf("Process %d reached unreachable code; claims to be the %dth process.\n", getpid(), *process); | |
exit(-1); | |
} | |
*writing_fd = pipe_fd[*process][1]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment