#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    51
    Rep Power
    10

    Posix Semaphore example using fork() and shared memory


    I am implementing some code that will create a shared memory segment and a shared semaphore between two processes. Once these are initialized I fork off into a parent/child and test the concurrency of updating the shared variable. Initially the shared variable is set to 345 and there should only be an output when the value is not 345. Unfortunately I am getting outputs of 346 and 347. Can someone give insight into why this code is not locking the critical sections correctly.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/shm.h>
    #include <semaphore.h>
    
    
    int main()
    {
      /* Declare fork variables */
      pid_t childpid;
    
      /* Declare shared memory variables */
      key_t key;
      int shmid;
      int *data;
      int prev = 345;
    
      /* Declare semaphore variables */
      sem_t *sem;
      int pshared = 1;
      unsigned int value = 1;
    
      /* Initialize Shared Memory */
      key = ftok("thread1.c",'R');
      shmid = shmget(key, 1024, 0644 | IPC_CREAT);
        
      /* Attach to Shared Memory */
      data = shmat(shmid, (void *)0, 0);
      if(data == (int *)(-1))
        perror("shmat");
    
      /* Write initial value to shared memory */
      *data = prev;
    
      /* Initialize Semaphore */
      if((sem_init(sem, pshared, value)) == 1)
        {
          perror("Error initializing semaphore");
          exit(1);
        }
    
      if((childpid = fork()) < 0) // error occured
        {
          perror("Fork Failed");
          exit(1);
        }
      else if(childpid == 0) // child process
        {
          /* Write to Shared Memory */
          while(1)
    	{
    	  sem_wait(sem);
    	  *data = *data + 1;
    	  *data = *data - 1;
    	  if(*data != prev)
    	    {
    	      printf("%d\n",*data);
    	      prev = *data;
    	    }
    	  sem_post(sem);
    	}
        }
      else // parent process
        {
          /* Write to Shared Memory */
          while(1)
    	{
    	  sem_wait(sem);
    	  *data = *data + 1;
    	  *data = *data - 1;
    	  sem_post(sem);
    	}
        }
      
      /* Detach from Shared Memory */
      shmdt(data);
    
      return 0;
    }
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,595
    Rep Power
    4207
    Your usage of the semaphore functions is borked. Matter of fact, I don't see how you're running this code without segfaulting. In the first place, you don't declare sem as a pointer to sem_t. You should declare it like this:
    Code:
    sem_t sem;
    Then call sem_init like this:
    Code:
    sem_init(&sem, pshared, value)
    and call sem_wait() and sem_post() like this:
    Code:
    sem_wait(&sem);
    sem_post(&sem);
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    51
    Rep Power
    10
    You're absolutely right. I realized that after I posted, made the exact corrections that you have suggested and I am still seeing a lack of concurrency control when writing to the shared memory. Is there something blatantly obvious that I am missing?
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,595
    Rep Power
    4207
    I'm going to guess because you're using them between processes instead of threads?
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    51
    Rep Power
    10
    So for processes I should use System V IPC Semaphores?
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,595
    Rep Power
    4207
    Most of the examples of process synchronization I've seen use SysV functions (semctl, semop etc.)
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo

IMN logo majestic logo threadwatch logo seochat tools logo