Skip to content

Instantly share code, notes, and snippets.

@DocBohn
Last active March 16, 2025 18:21
Show Gist options
  • Save DocBohn/627c40a63a091e7bfc80040b53e10792 to your computer and use it in GitHub Desktop.
Save DocBohn/627c40a63a091e7bfc80040b53e10792 to your computer and use it in GitHub Desktop.
Demonstration of using a pipe to communicate between processes
#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