JAN
JAN

Reputation: 21875

How can I check the state of a semaphore in c?

I have a global static variable that is a semaphore , since I'm writing a library and not a program .

Within a main() program that uses the library there are invokes of fork() , and reading & writing into/from a pipe , based on a shared memory .

For example , this is main() that uses my library :

#include <stdio.h>
#include <stdlib.h>
#include "my_pipe_shared_memory_based.h"
int main()

{
    int spd, pid, rb;
    char buff[4096];
    my_new_init();

    if (my_new_fifo("tmp_shm_pipe",0666) < 0)
    {
        perror("my_new_fifo");
        exit(1);
    }

    if (fork()) 
    {
        spd = my_new_open("tmp_shm_pipe", O_RDONLY, 0600);
        if (spd < 0)
        {
            perror("PARENT: my_new_open");
            exit(1);
        }
        rb = my_new_read(spd, buff, sizeof(buff));
        if (rb > 0)
            write(1, buff, rb);
    }

    else
    {
        spd = my_new_open("tmp_shm_pipe", O_WRONLY, 0600);
        if (spd < 0)
        {
            perror("SON: my_new_open");
            exit(1);
        }
        my_new_write(spd, "hello world!\n", sizeof("hello world!\n"));
    }

    my_new_close(spd);
    my_new_un_link("tmp_shm_pipe");
    my_new_finish();

    return 0;
}

Now , I want to use a semaphore before each time that a process is reading and/or writing in the methods :

  1. my_new_write()

  2. my_new_read()

Now , the question is , how can I check the state of the semaphore each time in the requested methods above (e.g. my_new_write & my_new_read) , so I can let the process do his thing , or block it , if another process is currently reading/writing ?

Thanks

Upvotes: 1

Views: 5423

Answers (2)

Jo&#227;o Fernandes
Jo&#227;o Fernandes

Reputation: 1101

The key thing here is that you have to make sure that the semaphore ensuring mutual exclusion is visible by both processes. To do that, you need to allocate shared memory and initialize the semaphore before forking. For this task you can for instance use mmap. Example (without any error checking):

sem_t *sem = mmap(NULL, sizeof(sem_t),
                  PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);

After this, use sem_init to initialize the semaphore and make sure that the second argument, pshared, is nonzero. Manual says:

If pshared is nonzero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent's memory mappings, it can also access the semaphore.) Any process that can access the shared memory region can operate on the semaphore using sem_post(3), sem_wait(3), etc.

Finally, fork the process and use sem_wait and sem_post normally.

EDIT:

Really, try to replace this:

mySemaphore = sem_open("mySemaphore", O_CREAT, S_IRUSR | S_IWUSR);

With this:

mySemaphore = mmap(NULL, sizeof(sem_t),
                   PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
sem_init(mySemaphore, 1, 1);

in function my_new_open

Upvotes: 2

Viktor Latypov
Viktor Latypov

Reputation: 14467

Isn't the sem_trywait() and sem_wait() the things you're looking for ? Call them with the semaphore handle and you will know their state.

http://pubs.opengroup.org/onlinepubs/7908799/xsh/sem_trywait.html

Not sure about semaphores, but the pthread_cond_timedwait() with a mutex may also allow you to check the state of synchronization without blocking the thread (or giving the timeout).

Upvotes: 1

Related Questions