Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save reloadedd/e6842c9a716b895fccc5c3ed69b9a549 to your computer and use it in GitHub Desktop.

Select an option

Save reloadedd/e6842c9a716b895fccc5c3ed69b9a549 to your computer and use it in GitHub Desktop.

Revisions

  1. reloadedd created this gist May 7, 2020.
    140 changes: 140 additions & 0 deletions supervisors_and_cooperating_workers.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    /* 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;
    }