Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sem post after sem wait doesn't work

Tags:

c

semaphore

I'm trying to create a pipe based shared memory. I'm also using semaphores, and I have a problem with one of my semaphores (maybe I do have more problems, but I didn't notice yet)

This semaphore initialization:

if (sem_init(&(sem_readers), 1, 0) < 0) {
    perror("Error sem_init");
    return -1;
}

The usage:

First the father (the reading end):

if (sem_wait(&(sem_readers)) < 0) {
    perror("ERROR: sem_wait i");
    return -1;
}

Then the son, the writing end:

if (sem_post(&(sem_readers)) < 0) {
    perror("ERROR: sem_post SEM_SHM_PIPE_PIPE");
    return -1;
}

For some reason, the father stucks on this wait() of the semaphore, even though the son do the post...

like image 935
hudac Avatar asked Jul 13 '26 06:07

hudac


2 Answers

You can't have unnamed semaphores in multiple processes, as they are stored only in memory and the memory for two processes are not shared.

You have to use sem_open to create a named semaphore before the fork, and then in the child process also use sem_open again to open the existing semaphore.

like image 168
Some programmer dude Avatar answered Jul 14 '26 21:07

Some programmer dude


The way you wrote your program the parent process and the child process work with two different semaphores. You can use a named semaphore as Joachim Pileborg pointed out, but you can also use unnamed semaphores between a process and its child, just store the semaphore in shared memory:

  /* place semaphore in shared memory */
  sem_t *mutex = mmap(NULL,sizeof(sem_t),
        PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
  if (!mutex) {
    perror("Out of memory");
  }

  /* create, initialize semaphore */
  if (sem_init(mutex, 1, 1) < 0) {
    perror("semaphore initilization");
    exit(0);
  }
  int ret = fork();

  //use your semaphore...

  if (sem_destroy(sema) < 0) {
    perror("sem_destroy failed: %s", strerror(errno));
    exit(0);
  }
  /* don't forget to unmap the memory */
  if (munmap(sema, sizeof(sem_t)) < 0) {
    perror("munmap failed: %s", strerror(errno));
    exit(0);
  }
like image 29
Étienne Avatar answered Jul 14 '26 21:07

Étienne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!