Created
November 11, 2013 13:12
-
-
Save junfenglx/7412986 to your computer and use it in GitHub Desktop.
named semaphores use example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> /* printf() */ | |
#include <stdlib.h> /* exit(), malloc(), free() */ | |
#include <unistd.h> | |
#include <sys/types.h> /* key_t, sem_t, pid_t */ | |
#include <sys/wait.h> | |
#include <sys/shm.h> /* shmat(), IPC_RMID */ | |
#include <errno.h> /* errno, ECHILD */ | |
#include <semaphore.h> /* sem_open(), sem_destroy(), sem_wait().. */ | |
#include <fcntl.h> /* O_CREAT, O_EXEC */ | |
int main (int argc, char **argv){ | |
int i; /* loop variables */ | |
key_t shmkey; /* shared memory key */ | |
int shmid; /* shared memory id */ | |
sem_t *sem; /* synch semaphore *//*shared */ | |
pid_t pid; /* fork pid */ | |
int *p; /* shared variable *//*shared */ | |
unsigned int n; /* fork count */ | |
unsigned int value; /* semaphore value */ | |
/* initialize a shared variable in shared memory */ | |
shmkey = ftok ("/dev/null", 5); /* valid directory name and a number */ | |
printf ("shmkey for p = %d\n", shmkey); | |
shmid = shmget (shmkey, sizeof (int), 0644 | IPC_CREAT); | |
if (shmid < 0){ /* shared memory error check */ | |
perror ("shmget\n"); | |
exit (1); | |
} | |
p = (int *) shmat (shmid, NULL, 0); /* attach p to shared memory */ | |
*p = 0; | |
printf ("p=%d is allocated in shared memory.\n\n", *p); | |
/********************************************************/ | |
printf ("How many children do you want to fork?\n"); | |
printf ("Fork count: "); | |
scanf ("%u", &n); | |
printf ("What do you want the semaphore value to be?\n"); | |
printf ("Semaphore value: "); | |
scanf ("%u", &value); | |
/* initialize semaphores for shared processes */ | |
sem = sem_open ("pSem", O_CREAT | O_EXCL, 0644, value); | |
/* name of semaphore is "pSem", semaphore is reached using this name */ | |
sem_unlink ("pSem"); | |
/* unlink prevents the semaphore existing forever */ | |
/* if a crash occurs during the execution */ | |
printf ("semaphores initialized.\n\n"); | |
/* fork child processes */ | |
for (i = 0; i < n; i++){ | |
pid = fork (); | |
if (pid < 0) /* check for error */ | |
printf ("Fork error.\n"); | |
else if (pid == 0) | |
break; /* child processes */ | |
} | |
/******************************************************/ | |
/****************** PARENT PROCESS ****************/ | |
/******************************************************/ | |
if (pid != 0){ | |
/* wait for all children to exit */ | |
while (pid = waitpid (-1, NULL, 0)){ | |
if (errno == ECHILD) | |
break; | |
} | |
printf ("\nParent: All children have exited.\n"); | |
/* shared memory detach */ | |
shmdt (p); | |
shmctl (shmid, IPC_RMID, 0); | |
/* cleanup semaphores */ | |
printf("sem_destroy return value:%d\n",sem_destroy (sem)); | |
exit (0); | |
} | |
/******************************************************/ | |
/****************** CHILD PROCESS *****************/ | |
/******************************************************/ | |
else{ | |
sem_wait (sem); /* P operation */ | |
printf (" Child(%d) is in critical section.\n", i); | |
sleep (1); | |
*p += i % 3; /* increment *p by 0, 1 or 2 based on i */ | |
printf (" Child(%d) new value of *p=%d.\n", i, *p); | |
sem_post (sem); /* V operation */ | |
exit (0); | |
} | |
} | |
/*src:http://stackoverflow.com/a/16400833*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I believe that the call of sem_destory at line 81 should be replaced by the call of comabination of sem_close and sem_unlink. Only by this way the file created by the sem_open at the /dev/shm/* could be properly removed.