-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathexer02c_producer_consumer.py
76 lines (49 loc) · 1.56 KB
/
exer02c_producer_consumer.py
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
'''
THE PRODUCER-CONSUMER PROBLEM
SOLUTION TYPE C: USING CONDITION VARIABLES & MONITORS
Multiple fast producers, multiple slow consumers
'''
import time
import threading
class Monitor:
def __init__(self, max_queue_size: int, q: list):
self.__q = q
self.__max_queue_size = max_queue_size
self.__lk = threading.Lock()
self.__cond_full = threading.Condition(self.__lk)
self.__cond_empty = threading.Condition(self.__lk)
def add(self, item):
with self.__lk:
while len(self.__q) == self.__max_queue_size:
self.__cond_full.wait()
self.__q.append(item)
if len(self.__q) == 1:
self.__cond_empty.notify()
def remove(self):
with self.__lk:
while len(self.__q) == 0:
self.__cond_empty.wait()
item = self.__q.pop(0)
if len(self.__q) == self.__max_queue_size - 1:
self.__cond_full.notify()
return item
def producer(mon: Monitor, start_value: int):
time.sleep(1)
i = 1
while True:
mon.add(i + start_value)
i += 1
def consumer(mon: Monitor):
while True:
data = mon.remove()
print('Consumer', data)
time.sleep(1)
MAX_QUEUE_SIZE = 6
NUM_PRODUCERS = 3
NUM_CONSUMERS = 2
q = []
monitor = Monitor(MAX_QUEUE_SIZE, q)
for i in range(NUM_PRODUCERS):
threading.Thread(target=producer, args=(monitor, i * 1000)).start()
for _ in range(NUM_CONSUMERS):
threading.Thread(target=consumer, args=(monitor,)).start()