0

I'm trying to write numbers (from 0-100 in incrementing order) on a file using two processes, where parent writes odd numbers and the child writes even numbers. result on the file should look like this:

1 2 3 4 5 6 ...... 100

to do so i tried synchronizing using named semaphores

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/wait.h>

FILE *ptr; //file pointer

sem_t *s_even, *s_odd; //declaring two semaphores

const char *even = "even", *odd = "odd"; //semaphore names

void fileWR(); // function containing fork call

void parent(); //parent which writes in file odd numbers only

void child(); //child which writes in file even numbers only

int main(void) {
    ptr = fopen("Semaphore.txt", "w+"); // openning the file

    fileWR();

    return 0;
}

// ***fileWR()***

void fileWR() {
    sem_unlink(even); //unlink any exsiting semaphores
    sem_unlink(odd);

    if (ptr == NULL) {
        fprintf(stderr, "ERROR!");
        exit(-1);
    }
    // i'm not handeling if fork failed

    if (fork() != 0) { // fork() process
        int status;

        //Parent
        //prints odd numbers only
        puts("####Parent#################");

        parent();

        wait(&status); // wait for child to terminate

    } else {
        //child
        //prints even numbers only

        puts("####Child#################");

        child();
    }
}

// ***parent()***

void parent() {
    int i = 0;

    //openning semaphore initialized at 0 since count starts 0

    s_odd = sem_open(odd, O_CREAT | O_EXCL, 0644, 0);

    if (s_odd == SEM_FAILED) {
        perror("Parent  : [sem_open] Failed\n");
        return;
    }

    while (i <= 100) {

        if (i % 2 != 0) { //id i is odd

            if (sem_wait(s_odd) != 0)
                perror("sem_wait"); //wait for child to finish writing in file

            //critical section
            //writing in file

            fprintf(ptr, "i=%d ", i);

            printf("i=%d ", i); //visualize what's being written on file

            if (sem_post(s_even) != 0)
                perror("sem_post"); //allow child to write
        }

        i++; //move to the next number      
    }
    //After printing all odd number and done with file and semaphore
    sem_unlink(odd);
    sem_close(s_odd);
    fclose(ptr);
}

// ***child()***

void child() {
    //semaphore initialized to 1 since since count starts with O
    s_even = sem_open(even, O_CREAT | O_EXCL, 0644, 1);
    if (s_even == SEM_FAILED) {
        perror("Child  : [sem_open] Failed\n");
        return;
    }

    int j = 0;
    while (j <= 100) {

        if (j % 2 == 0) { //if current number is even

            if (sem_wait(s_even) != 0)
                perror("sem_wait"); //waiting for parent to finish writing

            //critical section
            //write in the file (excepcted to execute first because s_even = 1
            fprintf(ptr, "j= %d ", j);
            printf("j=%d ", j); // visualize what's being written in the file

            if (sem_post(s_odd))
                perror("sem_post"); // allow parent to write
        }
        j++; //move to the next number
    }
    //After printing all even number and done with file and semaphore
    sem_unlink(even);
    sem_close(s_even);
    fclose(ptr);
}

This is my approach to solve the problem.

When I execute the program

####Parent#################
####Child#################

and nothing seems to happen after. I'm supposing there's something wrong with semaphore implementation? (Edit: I've updated my code and the segmentation fault was fixed)

Bodo
  • 9,287
  • 1
  • 13
  • 29
yazzy
  • 36
  • 3
  • 2
    Please try to create a [mre] to show us. What is `s1` and `s2` for example? And please ensure that the indentation is consistent. – Some programmer dude Jan 18 '23 at 09:49
  • And have you tried to use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to catch the crash, and locate where in *your* code it happens? – Some programmer dude Jan 18 '23 at 09:49
  • 1
    `s_even` is a null pointer in the parent process and `s_odd` is a null pointer in the child process. It is not surprising that calls to various `sem_...` functions will crash when passed a null pointer. – Ian Abbott Jan 18 '23 at 09:59
  • ```(fork() != 0)``` if it's -1, then ```fork``` failed. – Harith Jan 18 '23 at 10:55
  • @Someprogrammerdude thanks for your reply, sorry i've updated my code. I did my best to make it understandable as possible as i can – yazzy Jan 18 '23 at 11:35
  • @IanAbbott hmm, thats a great point, i shall pass them as arguments then. I'm going to try it. – yazzy Jan 18 '23 at 11:37
  • @Haris thanks for you reply, i mentionned that i'm not handeling case of (-1), since i'm tracking fork() success by printing which process i'm in. – yazzy Jan 18 '23 at 11:44
  • @IanAbbott i tried passing them as double pointer but it doesn't seem to work. Since you've mentionned it, declaring them as global variable wouldn't be enough ? – yazzy Jan 18 '23 at 11:47
  • 1
    Please don't split your code into separate blocks unless it must be in separate files. Use tools to check for memory access errors or undefined behavior, e.g. `gcc`'s options `-fsanitize=address -fsanitize=undefined`. see https://airbus-seclab.github.io/c-compiler-security/ You probably have to open the semaphores before `fork` – Bodo Jan 18 '23 at 12:37
  • Thanks for your edit, and you suggestion, i moved all the blocks into the main block, and opened semaphores before `fork` as you've suggested. ran `gcc` with the listed options and nothing was generated. FINALLY my code executes without any errors, BUT i'm not getting the expected result. CHILD process write all even numbers then PARENT writes odd numbers after. – yazzy Jan 18 '23 at 13:46

0 Answers0