modified: myjupyterlab.sh
[GalaxyCodeBases.git] / c_cpp / pthreadtest / 05bounded.c
blobdc7d24900c9ad3713d9d3f351e3bf9189bf78b26
1 /* bounded.c */
2 /* Code for Producer/Consumer problem using mutex and condition variables */
3 /* To compile me for Unix, type: gcc -o filename filename.c -lpthread */
5 #include <pthread.h>
6 #include <stdio.h>
8 #define BSIZE 4
9 #define NUMITEMS 30
11 typedef struct {
12 char buf[BSIZE];
13 int occupied;
14 int nextin, nextout;
15 pthread_mutex_t mutex;
16 pthread_cond_t more;
17 pthread_cond_t less;
18 } buffer_t;
20 buffer_t buffer;
22 void * producer(void *);
23 void * consumer(void *);
26 #define NUM_THREADS 2
27 pthread_t tid[NUM_THREADS]; /* array of thread IDs */
29 main( int argc, char *argv[] )
31 int i;
33 pthread_cond_init(&(buffer.more), NULL);
34 pthread_cond_init(&(buffer.less), NULL);
36 pthread_create(&tid[1], NULL, consumer, NULL);
37 pthread_create(&tid[0], NULL, producer, NULL);
38 for ( i = 0; i < NUM_THREADS; i++)
39 pthread_join(tid[i], NULL);
41 printf("\nmain() reporting that all %d threads have terminated\n", i);
43 } /* main */
47 void * producer(void * parm)
49 char item[NUMITEMS]="IT'S A SMALL WORLD, AFTER ALL.";
50 int i;
52 printf("producer started.\n");
54 for(i=0;i<NUMITEMS;i++)
55 { /* produce an item, one character from item[] */
57 if (item[i] == '\0') break; /* Quit if at end of string. */
59 pthread_mutex_lock(&(buffer.mutex));
61 if (buffer.occupied >= BSIZE) printf("producer waiting.\n");
62 while (buffer.occupied >= BSIZE)
63 pthread_cond_wait(&(buffer.less), &(buffer.mutex) );
64 printf("producer executing.\n");
66 buffer.buf[buffer.nextin++] = item[i];
67 buffer.nextin %= BSIZE;
68 buffer.occupied++;
70 /* now: either buffer.occupied < BSIZE and buffer.nextin is the index
71 of the next empty slot in the buffer, or
72 buffer.occupied == BSIZE and buffer.nextin is the index of the
73 next (occupied) slot that will be emptied by a consumer
74 (such as buffer.nextin == buffer.nextout) */
76 pthread_cond_signal(&(buffer.more));
77 pthread_mutex_unlock(&(buffer.mutex));
79 printf("producer exiting.\n");
80 pthread_exit(0);
83 void * consumer(void * parm)
85 char item;
86 int i;
88 printf("consumer started.\n");
90 for(i=0;i<NUMITEMS;i++){
92 pthread_mutex_lock(&(buffer.mutex) );
94 if (buffer.occupied <= 0) printf("consumer waiting.\n");
95 while(buffer.occupied <= 0)
96 pthread_cond_wait(&(buffer.more), &(buffer.mutex) );
97 printf("consumer executing.\n");
99 item = buffer.buf[buffer.nextout++];
100 printf("%c\n",item);
101 buffer.nextout %= BSIZE;
102 buffer.occupied--;
104 /* now: either buffer.occupied > 0 and buffer.nextout is the index
105 of the next occupied slot in the buffer, or
106 buffer.occupied == 0 and buffer.nextout is the index of the next
107 (empty) slot that will be filled by a producer (such as
108 buffer.nextout == buffer.nextin) */
110 pthread_cond_signal(&(buffer.less));
111 pthread_mutex_unlock(&(buffer.mutex));
113 printf("consumer exiting.\n");
114 pthread_exit(0);