zoe
zoe

Reputation: 1

semaphore between two processes doesn't work using fork

trying to create semaphore rutine between two processes but code seems to break too early. Tried to compare with other students who succeeded and our codes looks almost the same except that my i do fork only after semget and semctl.

   #include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
int main()
{
    pid_t n;
    int semid;
    int key = 98757;
    short sarray[1] = {2};
    struct sembuf sops[1];
    int err;

    semid = semget(key, 1, IPC_CREAT | 0666);
    if (semid == -1)
    {
        perror("semid failed");
        return 0;
    }

    err = semctl(semid, 1, SETALL, sarray);
    if (err == -1);/*code beakes down here*/
    {
        perror("semctl failed");

        return 0;
    }

    n = fork();

    if (n < 0)
    {
        printf("n < 0");
        return 0;
    }
    else if (n==0)/*child*/
    {
        sops[0].sem_num = 0;
        sops[0].sem_op = 0;
        sops[0].sem_flg = 0;
        err = semop(semid, sops, 1);
        if (err < 0)
        {
            printf("debugging semid < 0");
            return 0;
        }
        printf("%d", n);
        exit(0);
    }
    else/*parent*/
    {
        sleep(3);
        sops[0].sem_num = 0;
        sops[0].sem_op = -1;
        sops[0].sem_flg = 0;
        err = semop(semid, sops, 1);
        if (err < 0)
        {
            printf("debugging semid < 0");
            return 0;
        }
        wait(0);
    }

    return 0;
}

Upvotes: 0

Views: 270

Answers (1)

M Oehm
M Oehm

Reputation: 29116

When you test err after calling semctl, there is an error in the if statement. The cause is hard to see and obscured my a comment that sits too close to the code.

Here is the test without that comment:

if (err == -1);
{
    perror("semctl failed");

    return 0;
}

The semicolon after the condition makes this an if with an empty body: The check is performed, but nothing is done.

The code block in curly braces is entered unconditionally, regardless of the value of err. Such blocks are legal and sometimes useful to structure your code and to define tightly scoped variables.

TL;DR: Remove the semicolon:

if (err == -1) {
    perror("semctl failed");
    return 0;
}

Upvotes: 2

Related Questions