Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save reloadedd/e6842c9a716b895fccc5c3ed69b9a549 to your computer and use it in GitHub Desktop.
Save reloadedd/e6842c9a716b895fccc5c3ed69b9a549 to your computer and use it in GitHub Desktop.
/* Solution for 'Supervisor & cooperating workers' pattern #6
* The program creates 4 anonymous pipes (1 for reading, 1 for reading, for each process. You have 2 processes => 2 x 2 = 4 anoynmous pipes)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define MAX_SIZE 1024
void handle_error(const char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
int count_occurrences(char ch, const char *str) {
int occurrences = 0;
for (int i = 0; str[i]; ++i)
if (ch == str[i])
occurrences++;
return occurrences;
}
int main()
{
int pipe1_child1[2], pipe2_child1[2], pipe1_child2[2], pipe2_child2[2];
char ch;
pid_t child1, child2;
if (pipe(pipe1_child1) == -1)
handle_error("[Error] When creating the first anonymous pipe: ");
if (pipe(pipe2_child1) == -1)
handle_error("[Error] When creating the first anonymous pipe: ");
if ((child1 = fork()) == -1)
handle_error("[Error] When forking the first child: ");
if (child1 == 0) {
// Executed by the first child
char buffer[MAX_SIZE], i, ch;
int index = 0, occurrences;
close(pipe1_child1[1]); // Close the writing end of the reading pipe
close(pipe2_child1[0]); // Close the reading end of the writing pipe
read(pipe1_child1[0], &ch, 1);
while (read(pipe1_child1[0], &i, 1) != 0)
if(index < MAX_SIZE)
buffer[index++] = i;
buffer[ (index == MAX_SIZE) ? MAX_SIZE - 1 : index ] = '\0';
printf("[%d] Read: %s\n", getpid(), buffer);
occurrences = count_occurrences(ch, buffer);
write(pipe2_child1[1], &occurrences, sizeof(int));
close(pipe2_child1[1]); // Close the writing end
close(pipe1_child1[0]); // Close the reading end
}else{
// Executed by the parent
if (pipe(pipe1_child2) == -1)
handle_error("[Error] When creating the second anonymous pipe: ");
if (pipe(pipe2_child2) == -1)
handle_error("[Error] When creating the second anonymous pipe: ");
if ((child2 = fork()) == -1)
handle_error("[Error] When forking the first child: ");
if (child2 == 0) {
// Executed by the second child
char buffer[MAX_SIZE], i, ch;
int index = 0, occurrences;
close(pipe1_child2[1]); // Close the writing end of the reading pipe
close(pipe2_child2[0]); // Close the reading end of the writing pipe
read(pipe1_child2[0], &ch, 1);
while (read(pipe1_child2[0], &i, 1) != 0)
if(index < MAX_SIZE)
buffer[index++] = i;
buffer[ (index == MAX_SIZE) ? MAX_SIZE - 1 : index ] = '\0';
printf("[%d] Read: %s\n", getpid(), buffer);
occurrences = count_occurrences(ch, buffer);
write(pipe2_child2[1], &occurrences, sizeof(int));
close(pipe2_child2[1]); // Close the writing end
close(pipe1_child2[0]); // Close the reading end
}else{
// Executed by the parent
close(pipe1_child1[0]); // Close the reading end (int the parent) of the child1's reading pipe
close(pipe2_child1[1]); // Close the writing end (in the parent) of the child1's writing pipe
close(pipe1_child2[0]); // Close the reading end (int the parent) of the child2's reading pipe
close(pipe2_child2[1]); // Close the writing end (in the parent) of the child2's writing pipe
int counter = 1, occurrences_child1, occurrences_child2;
printf("Enter a sequence of characters, ended by CTRL + D.\n");
ch = getchar(); // Reading the fist character and sending it to both childs
write(pipe1_child1[1], &ch, 1);
write(pipe1_child2[1], &ch, 1);
while ((ch = getchar()) != EOF) {
if (counter % 2 == 0) // characters from even positions will be sent to the first child
write(pipe1_child1[1], &ch, 1);
else // characters from even positions will be sent to the first child
write(pipe1_child2[1], &ch, 1);
counter++;
}
// Closing the write end on the parent, so that the childs can receive EOF
close(pipe1_child1[1]);
close(pipe1_child2[1]);
read(pipe2_child1[0], &occurrences_child1, sizeof(int));
read(pipe2_child2[0], &occurrences_child2, sizeof(int));
printf("[PARENT] Received from the first child, with PID = %d: %d\n", child1, occurrences_child1);
printf("[PARENT] Received from the second child, with PID = %d: %d\n", child2, occurrences_child2);
printf("[PARENT] The sum of both occurrences is: %d\n", occurrences_child1 + occurrences_child2);
// Close the childs' reading ends on the parent
close(pipe2_child1[0]);
close(pipe2_child2[0]);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment