Created
May 7, 2020 07:56
-
-
Save reloadedd/e6842c9a716b895fccc5c3ed69b9a549 to your computer and use it in GitHub Desktop.
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
| /* 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