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()

  

 

 

 

 

posted @ 2022-02-25 15:52  ascertain  阅读(160)  评论(0编辑  收藏  举报