Last active
May 13, 2021 03:11
-
-
Save ckhung/c5c155836e9485bb85e42d4f41027676 to your computer and use it in GitHub Desktop.
multiple producers and multiple consumers working on the same queue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
# slightly modified from https://stackoverflow.com/questions/53778588/two-condition-variables-attached-to-the-same-lock-different-behaviors-in-python | |
# 也請見 「概念性、宏觀視野的程序/執行緒同步機制總覽」 | |
# https://newtoypia.blogspot.com/2017/12/synchronization.html | |
# Note: pip3 install colored | |
from threading import Thread, Lock, Condition | |
import time | |
from random import random, randint | |
import colored | |
from colored import stylize | |
queue = [] | |
CAPACITY = 3 | |
qlock = Lock() | |
item_ok = Condition(qlock) | |
space_ok = Condition(qlock) | |
class ProducerThread(Thread): | |
def run(self): | |
global queue | |
mycolor = self.name | |
while True: | |
qlock.acquire() | |
while len(queue) >= CAPACITY: | |
print(stylize('queue is full, stop producing', colored.fg(mycolor))) | |
space_ok.wait() | |
if len(queue) >= CAPACITY: | |
print(stylize('oops, someone filled the space before me', colored.fg(mycolor))) | |
item = chr(ord('A')+randint(0,25)) | |
print(stylize('['+' '.join(queue)+'] <= '+item, colored.fg( mycolor))) | |
queue.append(item) | |
item_ok.notify() | |
qlock.release() | |
time.sleep((random()+1)*1.5) | |
class ConsumerThread(Thread): | |
def run(self): | |
global queue | |
mycolor = self.name | |
while True: | |
qlock.acquire() | |
while not queue: | |
print(stylize('queue is empty, stop consuming', colored.fg(mycolor))) | |
item_ok.wait() | |
if not queue: | |
print(stylize('oops, someone consumed the food before me', colored.fg(mycolor))) | |
item = queue.pop(0) | |
print(stylize(item+' <= ['+' '.join(queue)+']', colored.fg( mycolor))) | |
space_ok.notify() | |
qlock.release() | |
time.sleep((random()+1)*1.5) | |
ProducerThread(name='red', daemon=True).start() | |
ProducerThread(name='green', daemon=True).start() | |
ProducerThread(name='blue', daemon=True).start() | |
ConsumerThread(name='cyan', daemon=True).start() | |
ConsumerThread(name='magenta', daemon=True).start() | |
ConsumerThread(name='yellow', daemon=True).start() | |
try: | |
while True: | |
time.sleep(3) | |
except KeyboardInterrupt: | |
print("Exiting") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
多個 producers 多個 consumers 的 python 程式。 注意: 本程式要用 python3 執行。 執行前請先以 pip3 install colored 安裝相依套件。 詳見 概念性、宏觀視野的程序/執行緒同步機制總覽。 感謝 stackoverflow 網友 Felix 的協助。