1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| /* ipcsemaphore.c
To compile : gcc -o sem ipcsemaphore.c
To run : ./sem */
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
union semun {
int val;
struct semid_ds *buf;
char *array;
};
void die(char *msg) {
perror(msg);
fflush(stdout);
fflush(stderr);
exit(1);
}
int main() {
int i,j;
int pid;
int semid; /* semid of semaphore set */
key_t key ; /* key to pass to semget() */
int semflg = IPC_CREAT | 0666; /* semflg to pass to semget() */
int nsems = 1; /* nsems to pass to semget() */
int nsops; /* number of operations to do */
struct sembuf *sops = (struct sembuf *) malloc(2*sizeof(struct sembuf));
/* ptr to operations to perform */
/* generate key */
/* if ((key = ftok("Semaphore", 'Q')) == -1)
die("ftok"); */
key=1234567890;
/* set up semaphore */
printf("\nsemget: Setting up semaphore: semget(%d, %d %o)\n", (int)key, nsems, semflg);
fflush(stdout);
fflush(stderr);
if ((semid = semget(key, nsems, semflg)) == -1)
die("semget: semget failed");
if ((pid = fork()) < 0)
die("fork");
if (pid == 0) {
/* child */
i = 0;
while (i < 3) { /* allow for 3 semaphore sets */
nsops = 2;
/* wait for semaphore to reach zero */
sops[0].sem_num = 0; /* We only use one track */
sops[0].sem_op = 0; /* wait for semaphore flag to become zero */
sops[0].sem_flg = SEM_UNDO; /* take off semaphore asynchronous */
sops[1].sem_num = 0;
sops[1].sem_op = 1; /* increment semaphore -- take control of track */
sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT; /* take off semaphore */
/* Recap the call to be made. */
printf("\nsemop:Child Calling semop(%d, &sops, %d) with:", semid, nsops);
for (j = 0; j < nsops; j++)
{
printf("\n\tsops[%d].sem_num = %d, ", j, sops[j].sem_num);
printf("sem_op = %d, ", sops[j].sem_op);
printf("sem_flg = %#o\n", sops[j].sem_flg);
}
/* Make the semop() call and report the results. */
if ((j = semop(semid, sops, nsops)) == -1)
{
perror("semop: semop failed");
} else {
printf("\n\nChild Process Taking Control of Track: %d/3 times\n", i+1);
sleep(5); /* DO Nothing for 5 seconds */
nsops = 1;
/* wait for semaphore to reach zero */
sops[0].sem_num = 0;
sops[0].sem_op = -1; /* Give UP COntrol of track */
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT; /* take off semaphore, asynchronous */
if ((j = semop(semid, sops, nsops)) == -1) {
perror("semop: semop failed");
} else {
printf("Child Process Giving up Control of Track: %d/3 times\n", i+1);
}
sleep(5); /* halt process to allow parent to catch semaphore change first */
}
++i;
}
} else { /* parent */
i = 0;
while (i < 3) { /* allow for 3 semaphore sets */
nsops = 2;
/* wait for semaphore to reach zero */
sops[0].sem_num = 0;
sops[0].sem_op = 0; /* wait for semaphore flag to become zero */
sops[0].sem_flg = SEM_UNDO; /* take off semaphore asynchronous */
sops[1].sem_num = 0;
sops[1].sem_op = 1; /* increment semaphore -- take control of track */
sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT; /* take off semaphore */
/* Recap the call to be made. */
printf("\nsemop:Parent Calling semop(%d, &sops, %d) with:", semid, nsops);
for (j = 0; j < nsops; j++) {
printf("\n\tsops[%d].sem_num = %d, ", j, sops[j].sem_num);
printf("sem_op = %d, ", sops[j].sem_op);
printf("sem_flg = %#o\n", sops[j].sem_flg);
}
/* Make the semop() call and report the results. */
if ((j = semop(semid, sops, nsops)) == -1) {
perror("semop: semop failed");
} else {
printf("Parent Process Taking Control of Track: %d/3 times\n", i+1);
sleep(5); /* Sleep for 5 seconds */
nsops = 1;
/* wait for semaphore to reach zero */
sops[0].sem_num = 0;
sops[0].sem_op = -1; /* Give UP Control of track */
sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT; /* take off semaphore, asynchronous */
if ((j = semop(semid, sops, nsops)) == -1) {
perror("semop: semop failed");
} else {
printf("Parent Process Giving up Control of Track: %d/3 times\n", i+1);
}
sleep(5); /* halt process to allow child to catch semaphore change first */
}
++i;
}
}
return 0;
} |
Partager