ceid-vg
ceid-vg

Reputation: 333

Semaphore example in C

I am trying to make a simple semaphore example in C in which, having two while loops, will produce this outcome without threads, using two diferrent processes :

abcd
abcd
abcd
abcd

Since I cannot use pthreads, I tried to make the common signal() and wait() methods but for some reasons, I get an error in the wakeup call inside my signal method.

#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

wait(sem_t *s)
{
    s=s-1;
    if (s<0) 
        block(); // add process to queue
}

signal(sem_t *s)
{
    s=s+1;
    if (s<=0) 
        wakeup(p); // remove process p from queue
}

init(sem_t *s , int v)
{
    s=v;
}

void main(void)
{
  int i;
  // place semaphore in shared memory
  sem_t *child_sem = mmap(NULL,sizeof(*child_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
  sem_t *parent_sem = mmap(NULL,sizeof(*parent_sem),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  init(child_sem, 1);  // create child semaphore
  init(parent_sem, 1); // create parent semaphore

  if (fork())
  {
      for (i = 0; i < 10; i++)
      {
           if (wait(child_sem) < 0)
                perror("sem_wait");
           printf("ab");
           if (signal(parent_sem) < 0)
                perror("sem_post");
           sleep(1); // required to maintain thread order
      }
  }
  else
  {
      for (i = 0; i < 10; i++)
      { // parent starts waiting
          if (wait(parent_sem) < 0) 
                perror("sem_wait");
          printf("cd\n");
          if (signal(child_sem) < 0)
                perror("sem_post");
      }
  }
}

Output:

[Error] In function 'signal':
[Error] 'p' undeclared (first use in this function)

The thing is that how could I enter a process p inside the wakeup call? Should I use a pid=fork() inside a method?

Should I use an extra argument in signal method but what would it be like? pid p ?

If I remove the p argument from wakeup, then variables like PROT_READ become undeclared for some reason.

P.S. The code is from this site.

Upvotes: 0

Views: 2638

Answers (1)

Mayukh Sarkar
Mayukh Sarkar

Reputation: 2625

I will not write the the whole thing but here is a better way to solve this.

  1. Use 2 semaphores.
  2. Run the first process when semaphore number 1 is high
  3. Run the second process when semaphore number 2 is high
  4. At the starting of the critical section of 1st process, make 2nd semaphore low so that the resource can not be used by the 2nd process
  5. At the end of the critical section of the 1st process, make the 2nd semaphore = 1 and 1st semaphore = 0
  6. Do exactly opposite for the second process, i.e., stating sem1 = 0, ending sem1 = 1, sem2 = 0.

This may solve the problem. Never use signal use sigaction instead.

Upvotes: 1

Related Questions