Created
August 16, 2011 04:12
-
-
Save vladimir-lu/1148426 to your computer and use it in GitHub Desktop.
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
Unix semaphore example | |
/* semabinit.c - initialize a semaphore for use by programs sema and semb */ | |
#include <sys/types.h> | |
#include <sys/ipc.h> | |
#include <sys/sem.h> | |
#include <stdio.h> | |
/* The semaphore key is an arbitrary long integer which serves as an | |
external identifier by which the semaphore is known to any program | |
that wishes to use it. */ | |
#define KEY (1492) | |
void main() | |
{ | |
int id; /* Number by which the semaphore is known within a program */ | |
/* The next thing is an argument to the semctl() function. Semctl() | |
does various things to the semaphore depending on which arguments | |
are passed. We will use it to make sure that the value of the | |
semaphore is initially 0. */ | |
union semun { | |
int val; | |
struct semid_ds *buf; | |
ushort * array; | |
} argument; | |
argument.val = 0; | |
/* Create the semaphore with external key KEY if it doesn't already | |
exists. Give permissions to the world. */ | |
id = semget(KEY, 1, 0666 | IPC_CREAT); | |
/* Always check system returns. */ | |
if(id < 0) | |
{ | |
fprintf(stderr, "Unable to obtain semaphore.\n"); | |
exit(0); | |
} | |
/* What we actually get is an array of semaphores. The second | |
argument to semget() was the array dimension - in our case | |
1. */ | |
/* Set the value of the number 0 semaphore in semaphore array | |
# id to the value 0. */ | |
if( semctl(id, 0, SETVAL, argument) < 0) | |
{ | |
fprintf( stderr, "Cannot set semaphore value.\n"); | |
} | |
else | |
{ | |
fprintf(stderr, "Semaphore %d initialized.\n", KEY); | |
} | |
} | |
/* Semaphore example program a (sema.c) */ | |
/* We have two programs, sema and semb. Semb may be initiated at any | |
time, but will be forced to wait until sema is executed. Sema and | |
semb do not have to be executed by the same user! */ | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/ipc.h> | |
#include <sys/sem.h> | |
#define KEY (1492) | |
/* This is the external name by which the semaphore is known to any | |
program that wishes to access it. */ | |
void main() | |
{ | |
int id; /* Internal identifier of the semaphore. */ | |
struct sembuf operations[1]; | |
/* An "array" of one operation to perform on the semaphore. */ | |
int retval; /* Return value from semop() */ | |
/* Get the index for the semaphore with external name KEY. */ | |
id = semget(KEY, 1, 0666); | |
if(id < 0) | |
/* Semaphore does not exist. */ | |
{ | |
fprintf(stderr, "Program sema cannot find semaphore, exiting.\n"); | |
exit(0); | |
} | |
/* Do a semaphore V-operation. */ | |
printf("Program sema about to do a V-operation. \n"); | |
/* Set up the sembuf structure. */ | |
/* Which semaphore in the semaphore array : */ | |
operations[0].sem_num = 0; | |
/* Which operation? Add 1 to semaphore value : */ | |
operations[0].sem_op = 1; | |
/* Set the flag so we will wait : */ | |
operations[0].sem_flg = 0; | |
/* So do the operation! */ | |
retval = semop(id, operations, 1); | |
if(retval == 0) | |
{ | |
printf("Successful V-operation by program sema.\n"); | |
} | |
else | |
{ | |
printf("sema: V-operation did not succeed.\n"); | |
perror("REASON"); | |
} | |
} | |
/* Think carefully about what the V-operation does. If sema is executed | |
twice, then semb can execute twice. */ | |
/* Semaphore example program b (semb.c) */ | |
/* We have two programs, sema and semb. Semb may be initiated at any | |
time, but will be forced to wait until sema is executed. Sema and | |
semb do not have to be executed by the same user! */ | |
/* HOW TO TEST: | |
Execute semb & | |
The & is important - otherwise you would have have to move to | |
a different terminal to execute sema. | |
Then execute sema. | |
*/ | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/ipc.h> | |
#include <sys/sem.h> | |
#define KEY (1492) | |
/* This is the external name by which the semaphore is known to any | |
program that wishes to access it. */ | |
void main() | |
{ | |
int id; /* Internal identifier of the semaphore. */ | |
struct sembuf operations[1]; | |
/* An "array" of one operation to perform on the semaphore. */ | |
int retval; /* Return value from semop() */ | |
/* Get the index for the semaphore with external name KEY. */ | |
id = semget(KEY, 1, 0666); | |
if(id < 0) | |
/* Semaphore does not exist. */ | |
{ | |
fprintf(stderr, "Program semb cannot find semaphore, exiting.\n"); | |
exit(0); | |
} | |
/* Do a semaphore P-operation. */ | |
printf("Program semb about to do a P-operation. \n"); | |
printf("Process id is %d\n", getpid()); | |
/* Set up the sembuf structure. */ | |
/* Which semaphore in the semaphore array : */ | |
operations[0].sem_num = 0; | |
/* Which operation? Subtract 1 from semaphore value : */ | |
operations[0].sem_op = -1; | |
/* Set the flag so we will wait : */ | |
operations[0].sem_flg = 0; | |
/* So do the operation! */ | |
retval = semop(id, operations, 1); | |
if(retval == 0) | |
{ | |
printf("Successful P-operation by program semb.\n"); | |
printf("Process id is %d\n", getpid()); | |
} | |
else | |
{ | |
printf("semb: P-operation did not succeed.\n"); | |
} | |
} | |
/* Think carefully about what the V-operation does. If sema is executed | |
twice, then semb can execute twice. */ | |
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<pthread.h> | |
#include<stdio.h> | |
#include<sys/types.h> | |
#include<semaphore.h> | |
#include<unistd.h> | |
pthread_t t1,t2; | |
pthread_attr_t tattr; | |
int counter; | |
sem_t mutex; | |
void* runner(void *arg) | |
{ | |
int i = 0; | |
printf("Thread received %i\n", *(int*)arg); | |
for(i = 0; i < 5; i++) | |
{ | |
sem_wait(&mutex); | |
printf("Thread %i says %i\n",*((int *)arg),counter); | |
counter++; | |
sem_post(&mutex); | |
sleep(1); | |
} | |
return (void*)NULL; | |
} | |
int main() | |
{ | |
int r; | |
int t = 1; | |
printf("hi"); | |
r = sem_init(&mutex,0,1); | |
r = pthread_attr_init(&tattr); | |
r = pthread_create(&t1,&tattr,runner,(void *)&t); | |
t = 2; | |
r = pthread_create(&t2,&tattr,runner,(void *)&t); | |
printf("Threads initialised"); | |
r = pthread_join(t1,NULL); | |
r = pthread_join(t2,NULL); | |
r = sem_destroy(&mutex); | |
return 0; | |
} | |
//////////// | |
#include <sys/types.h> | |
#include <stdio.h> | |
#include <sys/ipc.h> | |
#include <sys/sem.h> | |
#include <sys/stat.h> | |
#include <errno.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <pwd.h> | |
#include <fcntl.h> | |
#include <limits.h> | |
... | |
key_t semkey; | |
int semid, pfd, fv; | |
struct sembuf sbuf; | |
char *lgn; | |
char filename[PATH_MAX+1]; | |
struct stat outstat; | |
struct passwd *pw; | |
... | |
/* Get unique key for semaphore. */ | |
if ((semkey = ftok("/tmp", 'a')) == (key_t) -1) { | |
perror("IPC error: ftok"); exit(1); | |
} | |
/* Get semaphore ID associated with this key. */ | |
if ((semid = semget(semkey, 0, 0)) == -1) { | |
/* Semaphore does not exist - Create. */ | |
if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | | |
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) | |
{ | |
/* Initialize the semaphore. */ | |
sbuf.sem_num = 0; | |
sbuf.sem_op = 2; /* This is the number of runs | |
without queuing. */ | |
sbuf.sem_flg = 0; | |
if (semop(semid, &sbuf, 1) == -1) { | |
perror("IPC error: semop"); exit(1); | |
} | |
} | |
else if (errno == EEXIST) { | |
if ((semid = semget(semkey, 0, 0)) == -1) { | |
perror("IPC error 1: semget"); exit(1); | |
} | |
} | |
else { | |
perror("IPC error 2: semget"); exit(1); | |
} | |
} | |
... |
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 "semstuff.hpp" | |
key_t getSemaphoreKey(char id) { | |
key_t semkey; | |
/* Get unique key for semaphore. */ | |
if ((semkey = ftok("/tmp", id)) == (key_t) -1) { | |
perror("IPC error: ftok"); exit(1); | |
} | |
printf("semkey A: %d\n", semkey); | |
return semkey; | |
} | |
int getSemaphore(key_t semkey) { | |
int semid = 0; | |
struct sembuf sbuf; | |
/* Get semaphore ID associated with this key. */ | |
if ((semid = semget(semkey, 0, 0)) == -1) { | |
/* Semaphore does not exist - Create. */ | |
if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | | |
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) | |
{ | |
/* Initialize the semaphore. */ | |
sbuf.sem_num = 0; | |
sbuf.sem_op = 1; /* This is the number of runs | |
without queuing. */ | |
sbuf.sem_flg = 0; | |
if (semop(semid, &sbuf, 1) == -1) { | |
perror("IPC error: semop"); exit(1); | |
} | |
} | |
else if (errno == EEXIST) { | |
if ((semid = semget(semkey, 0, 0)) == -1) { | |
perror("IPC error 1: semget"); exit(1); | |
} | |
} | |
else { | |
perror("IPC error 2: semget"); exit(1); | |
} | |
} | |
printf("semid: %d\n", semid); | |
return semid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment