-
Notifications
You must be signed in to change notification settings - Fork 0
/
threadsProducerConsumer.c
123 lines (89 loc) · 2.79 KB
/
threadsProducerConsumer.c
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#include "macros.h"
#define BUFFER_SIZE 10
#define N_PRODUCERS 4
#define N_CONSUMERS 4
#define N_MESSAGES 20
#define MAX_SIZE 256
// Circular buffer
char buffer[BUFFER_SIZE][MAX_SIZE];
int head = 0, tail = 0;
// Mutex and condition variables
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
// Function prototypes
void *producer(void *arg);
void *consumer(void *arg);
int main() {
pthread_t producers[N_PRODUCERS], consumers[N_CONSUMERS];
int i, retvalue;
// Seed the random number generator
srand(22);
// Create producer threads
for (i = 0; i < N_PRODUCERS; ++i)
SYST(pthread_create(&producers[i], NULL, producer, NULL));
// Create consumer threads
for (i = 0; i < N_CONSUMERS; ++i)
SYST(pthread_create(&consumers[i], NULL, consumer, NULL));
// Wait for all threads to terminate
for (i = 0; i < N_PRODUCERS; ++i)
SYST(pthread_join(producers[i], NULL));
for (i = 0; i < N_CONSUMERS; ++i)
SYST(pthread_join(consumers[i], NULL));
return 0;
}
void *producer(void *arg) {
int i;
char message[MAX_SIZE];
for (i = 0; i < N_MESSAGES; ++i) {
// Generate a random message
sprintf(message, "Message %d from producer %ld\n", i, pthread_self());
// Lock the mutex
pthread_mutex_lock(&mutex);
// Wait until the buffer is not full
while ((head + 1) % BUFFER_SIZE == tail) {
pthread_cond_wait(¬_full, &mutex);
}
// Write the message in the buffer
strcpy(buffer[head], message);
head = (head + 1) % BUFFER_SIZE;
// Signal that the buffer is not empty
pthread_cond_signal(¬_empty);
// Unlock the mutex
pthread_mutex_unlock(&mutex);
// Sleep for a random time
usleep((rand() % 100) * 1000);
}
return NULL;
}
void *consumer(void *arg) {
int i;
char message[MAX_SIZE];
for (i = 0; i < N_MESSAGES; ++i) {
// Lock the mutex
pthread_mutex_lock(&mutex);
// Wait until the buffer is not empty
while (head == tail) {
pthread_cond_wait(¬_empty, &mutex);
}
// Read the message from the buffer
strcpy(message, buffer[tail]);
tail = (tail + 1) % BUFFER_SIZE;
// Signal that the buffer is not full
pthread_cond_signal(¬_full);
// Unlock the mutex
pthread_mutex_unlock(&mutex);
// Print the message
printf("%s", message);
// Sleep for a random time
usleep((rand() % 100) * 1000);
}
return NULL;
}