Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 线程-具有计数器对象的生产者/消费者_Python_Python 3.x_Multithreading - Fatal编程技术网

Python 线程-具有计数器对象的生产者/消费者

Python 线程-具有计数器对象的生产者/消费者,python,python-3.x,multithreading,Python,Python 3.x,Multithreading,我在下面编写了一段代码片段,旨在实现以下目标。我有一个计数器对象,在所有消费者之间共享,这些消费者在完成任务后,增加计数器并耐心等待。这个想法是创建一个新的ip地址,其他线程可以在他们的新任务中使用,这将由生产者完成,生产者还将检查计数器是否有价值,如果有,它将创建一个新的ip并通知所有人,否则通知所有人而不创建新的ip。但由于某些原因,我从未收到不设置新IP地址的消息。有人能告诉我为什么吗 多谢各位: import logging import threading import time im

我在下面编写了一段代码片段,旨在实现以下目标。我有一个计数器对象,在所有消费者之间共享,这些消费者在完成任务后,增加计数器并耐心等待。这个想法是创建一个新的ip地址,其他线程可以在他们的新任务中使用,这将由生产者完成,生产者还将检查计数器是否有价值,如果有,它将创建一个新的ip并通知所有人,否则通知所有人而不创建新的ip。但由于某些原因,我从未收到不设置新IP地址的
消息。有人能告诉我为什么吗

多谢各位:

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

尝试在生产者线程内添加锁

其他线程应该等待生产者完成其任务

这可以防止在生产者线程执行期间计数器被其他线程覆盖

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