Python: threading.Condition

消费速度 > 生产速度
import threading, time, logging, random FORMAT = '%(asctime)-15s [%(threadName)-11s %(thread)6d] %(message)s' logging.basicConfig(format=FORMAT, level=logging.DEBUG) class Dispatcher: def __init__(self): self.data = None self.event = threading.Event() def produce(self, total): for _ in range(total): data = random.randrange(1, 100, 2) logging.info(data) self.data = data self.event.wait(1) self.event.set() def consume(self): while not self.event.is_set(): logging.info(f'consume {self.data}') self.data = None self.event.wait(0.5) d = Dispatcher() p = threading.Thread(name='producer', target=d.produce, args=(10,)) c = threading.Thread(name='consumer', target=d.consume) c.start() p.start()
import threading, time, logging, random
logging.basicConfig(format='{asctime:<20} {levelname} {threadName:<10}: {message}', datefmt='%Y-%m-%d %H:%M:%S', style='{', level=logging.DEBUG)
class Dispatcher:
def __init__(self):
self.data = None
self.event = threading.Event()
self.condition = threading.Condition()
def produce(self, total):
for _ in range(total):
with self.condition:
data = random.randrange(1, 100, 2)
logging.info(f'produce {data}')
self.data = data
# If the calling thread has not acquired the lock when this method is called, a RuntimeError is raised
# An awakened thread does not actually return from its wait() call until it can reacquire the lock, Since notify() does not release the lock, its caller should
# self.condition.notify_all()
self.condition.notify(n=1)
self.event.wait(0.4) # imitate producer velocity
self.event.set()
with self.condition: # 将consumer从self.condition.wait()中唤醒
self.condition.notify_all() # 结束consumer的 self.condition.wait()
def consume(self):
while not self.event.is_set():
with self.condition:
# logging.info(f'consumer wait pre {self.event.is_set()} {threading.enumerate()}')
self.condition.wait() # block wait for notify
logging.info(f'consume {self.data}')
self.data = None
self.event.wait(0.2) # imitate consumer velocity
d = Dispatcher()
p = threading.Thread(name='producer', target=d.produce, args=(10,))
for i in range(1, 6):
c = threading.Thread(name=f'consumer-{i}', target=d.consume)
c.start()
p.start()



浙公网安备 33010602011771号