[英]Threading - Producers/Consumers with a Counter object
I have written a code snippet below that aims to achieve the following. 我在下面编写了一个代码片段,旨在实现以下目标。 I have a counter object that is shared between all of the consumers, these consumers, upon completion of their task, increment the counter and wait patiently. 我有一个在所有使用者之间共享的计数器对象,这些使用者在完成任务后增加计数器并耐心等待。 The idea is to create a new ip address that the other threads can then use in their new task, this will be done by the producer, who also checks if the counter is of some value, and if it is, it will create a new ip and notify everyone, otherwise notify everyone without creating a new ip. 这个想法是创建一个新的ip地址,其他线程然后可以在其新任务中使用它,这将由生产者完成,生产者还将检查计数器是否具有一定的价值,如果存在,它将创建一个新的ip并通知所有人,否则通知所有人而不创建新的ip。 But for some reason, I never get the NOT SETTING A NEW IP ADDRESS
message. 但是由于某种原因,我从未收到“ NOT SETTING A NEW IP ADDRESS
消息。 Can someone tell me why? 有人可以告诉我为什么吗?
Thanks a bunch: 感谢一群:
import logging
import threading
import time
import random
class Counter(object):
def __init__(self, start=0):
self.lock = threading.RLock()
self.value = start
def increment(self):
logging.debug('Waiting for lock')
with self.lock:
logging.debug('Acquired lock. Current counter value: {}'.format(self.value + 1))
self.value = self.value + 1
def consumer(cond, counter):
"""wait for the condition and use the resource"""
logging.debug('Starting consumer thread')
while True:
time_sleep = random.randint(5, 10) / 5
time.sleep(time_sleep)
with cond:
counter.increment()
logging.debug('Resource is available to consumer. Doing some werk on counter {}'.format(counter.value))
logging.debug('Done some werk. Waiting for other threads to finish their werk and for producer to signal continuation.')
cond.wait()
def producer(cond, counter):
"""set up the resource to be used by the consumer"""
logging.debug('Starting producer thread')
for i in range(4):
logging.debug('Producer sleeping for 3 seconds')
time.sleep(3)
with cond:
if counter.value % 2 == 0:
logging.debug('Setting a new ip address')
cond.notifyAll()
if counter.value % 2 != 0:
logging.debug('NOT SETTING A NEW IP ADDRESS')
cond.notifyAll()
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s (%(threadName)-2s) %(message)s',
)
condition = threading.Condition()
c = Counter()
c1 = threading.Thread(name='c1', target=consumer,
args=(condition, c))
c2 = threading.Thread(name='c2', target=consumer,
args=(condition, c))
p = threading.Thread(name='p', target=producer,
args=(condition, c))
c1.start()
c2.start()
p.start()
Try adding a lock inside the producer thread. 尝试在生产者线程内添加锁。
Other thread should wait for the producer to do its task. 其他线程应等待生产者执行其任务。
This prevents counter being overwritten by the other thread during the execution of producer thread. 这样可以防止在生产者线程执行期间计数器被另一个线程覆盖。
def producer(cond, counter):
"""set up the resource to be used by the consumer"""
logging.debug('Starting producer thread')
with self.lock
for i in range(4):
logging.debug('Producer sleeping for 3 seconds')
time.sleep(3)
with cond:
if counter.value % 2 == 0:
logging.debug('Setting a new ip address')
cond.notifyAll()
if counter.value % 2 != 0:
logging.debug('NOT SETTING A NEW IP ADDRESS')
cond.notifyAll()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.