-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.c
151 lines (111 loc) · 3.72 KB
/
main.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
int *buffer;
int bufferSize; //agr1
int taken = 0;
int producerMaxSleep;//arg2
int consumerMaxSleep;//arg3
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//display operation and taken variable modifier locker
pthread_mutex_t mutexP = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condP = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutexC = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condC = PTHREAD_COND_INITIALIZER;
void *Produce(void *arg);
void *Consume(void *arg);
void Display(int n);
int main(int argc, char *argv[]) {
if (argc < 4) {
printf("Not enough arguments\n 1. Buffer Size\n 2. Producer Max Sleep [ms]\n 3. Consumer Max Sleep[ms]\n");
return 0;
} else {
bufferSize = atoi(argv[1]);
buffer = malloc(bufferSize * sizeof(int));
producerMaxSleep = atoi(argv[2]);
consumerMaxSleep = atoi(argv[3]);
}
srand(time(NULL));
int i;
for (i = 0; i < bufferSize; ++i) //prepare empty array
buffer[i] = 0;
pthread_t producer, consumer;
if (pthread_create(&producer, NULL, Produce, NULL)) {
printf("Create thread error\n");
abort();
}
if (pthread_create(&consumer, NULL, Consume, NULL)) {
printf("Create thread error\n");
abort();
}
if (pthread_join(producer, NULL)) {
printf("Join thread error\n");
}
if (pthread_join(consumer, NULL)) {
printf("Join thread error\n");
}
free(buffer);
return 0;
}
void *Produce(void *arg) {
int counter = 1000;
int indexProducer = 0;
int sleepTime;
while (1) {
sleepTime = rand() % producerMaxSleep; //[0 - producerMaxSleep)
pthread_mutex_lock(&mutexP);
if (taken == bufferSize) {
pthread_cond_wait(&condP, &mutexP); //Wait for a place in buffer
}
pthread_mutex_unlock(&mutexP);
buffer[indexProducer] = counter++; //Element produced
pthread_mutex_lock(&mutex);
taken++; //Adjust elements number in buffer
pthread_mutex_unlock(&mutex);
indexProducer = (indexProducer + 1) % bufferSize;
pthread_mutex_lock(&mutex);
printf("%6d -> ", counter - 1);
Display(bufferSize);
printf("\n\n");
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condC); //Buffer is not empty. I have added something.
sleep(sleepTime / 1000);
}
return NULL;
}
void *Consume(void *arg) {
int indexConsumer = 0;
int sleepTime;
int tmp;
while (1) {
sleepTime = rand() % consumerMaxSleep;
pthread_mutex_lock(&mutexC);
if (taken == 0) {
pthread_cond_wait(&condC, &mutexC); //Wait until buffer is not empty
}
pthread_mutex_unlock(&mutexC);
tmp = buffer[indexConsumer];
buffer[indexConsumer] = 0; //Element consumed
pthread_mutex_lock(&mutex);
taken--; //Adjust elements number in buffer
pthread_mutex_unlock(&mutex);
indexConsumer = (indexConsumer + 1) % bufferSize;
pthread_mutex_lock(&mutex);
printf(" ");
Display(bufferSize);
printf("-> %6d \n\n", tmp);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condP); //There is empty space in buffer. You can add something.
sleep(sleepTime / 1000);
}
return NULL;
}
void Display(int n) { //display buffer
int i;
for (i = 0; i < n; ++i) {
printf("| %6d ", buffer[i]);
}
printf("|");
}