15
Semaphore
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- typedef struct {
- int count;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- } semaphore;
- void sema_init( semaphore *sp, int count ) {
- sp->count = count;
- pthread_mutex_init( &sp->mutex, 0 );
- pthread_cond_init( &sp->cond, 0 );
- }
- void sema_destroy( semaphore *sp ) {
- pthread_mutex_destroy( &sp->mutex );
- pthread_cond_destroy( &sp->cond );
- }
- void sema_acquire( semaphore *sp ) {
- pthread_mutex_lock( &sp->mutex );
- while ( sp->count == 0 )
- pthread_cond_wait( &sp->cond, &sp->mutex );
- --sp->count;
- pthread_mutex_unlock( &sp->mutex );
- }
- void sema_release( semaphore *sp ) {
- pthread_mutex_lock( &sp->mutex );
- ++sp->count;
- pthread_cond_broadcast( &sp->cond );
- pthread_mutex_unlock( &sp->mutex );
- }
- typedef struct {
- int id;
- semaphore *sema;
- pthread_t thread;
- } user;
- void *work( void *p ) {
- int id = ((user *) p)->id;
- semaphore *sp = ((user *) p)->sema;
- int i, n;
- printf( "%d - Acquiring resource\n", id );
- sema_acquire( sp );
- printf( "%d - Resource is locked\n", id );
- n = (double) rand() / RAND_MAX * 10000000;
- printf( "%d * Busy(%d)...\n", id, n );
- for ( i = 0; i < n; i++ )
- (void) rand();
- printf( "%d - Releasing resource\n", id );
- sema_release( sp );
- pthread_exit( 0 );
- }
- #define NUSERS 7
- int main( int argc, char *argv[] ) {
- pthread_attr_t attr;
- void *status;
- user people[NUSERS];
- semaphore sema;
- int i;
- srand( time( 0 ) );
- sema_init( &sema, 2 );
- pthread_attr_init( &attr );
- pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
- for ( i = 0; i < NUSERS; i++ ) {
- user *p = &people[i];
- p->id = i + 1;
- p->sema = &sema;
- pthread_create( &p->thread, &attr, work, (void *) p );
- }
- // MUST be in a separate loop!
- for ( i = 0; i < NUSERS; i++ )
- pthread_join( people[i].thread, &status );
- pthread_attr_destroy( &attr );
- sema_destroy( &sema );
- pthread_exit( 0 );
- }
$ gcc -Wall -lpthread sema.c -o sema
$ ./sema
1 - Acquiring resource
1 - Resource is locked
2 - Acquiring resource
6 - Acquiring resource
4 - Acquiring resource
4 - Resource is locked
4 * Busy(6893328)...
5 - Acquiring resource
7 - Acquiring resource
1 * Busy(5600318)...
3 - Acquiring resource
1 - Releasing resource
5 - Resource is locked
5 * Busy(4001876)...
4 - Releasing resource
3 - Resource is locked
3 * Busy(6268161)...
5 - Releasing resource
6 - Resource is locked
6 * Busy(9453382)...
3 - Releasing resource
7 - Resource is locked
7 * Busy(5335524)...
7 - Releasing resource
2 - Resource is locked
2 * Busy(5401617)...
6 - Releasing resource
2 - Releasing resource
Comments