python - 线程条件变量 : un-acquired lock

标签 python multithreading python-3.x python-2.x

我在 Python 中有这个示例,它演示了条件变量的使用。

import logging
import threading
import time

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s (%(threadName)-2s) %(message)s',)

def consumer(cond):

    # wait for the condition and use the resource

    logging.debug('Starting consumer thread')

    t = threading.currentThread()

    cond.wait()

    logging.debug('Resource is available to consumer')

def producer(cond):

    # set up the resource to be used by the consumer

    logging.debug('Starting producer thread')

    logging.debug('Making resource available')

    cond.notifyAll()


condition = threading.Condition()

# pass each thread a 'condition'
c1 = threading.Thread(name='c1', target=consumer, args=(condition,))
c2 = threading.Thread(name='c2', target=consumer, args=(condition,))
p = threading.Thread(name='p', target=producer, args=(condition,))


# start two threads and put them into 'wait' state
c1.start()
c2.start()

# after two seconds or after some operation notify them to free or step over the wait() function
time.sleep(2)
p.start()

但是,它会在线程上引发运行时错误un-acquired lock。我有一个想法,我需要使用 acquirerelease 函数,但我不确定它们的用法以及它们究竟做了什么。

最佳答案

条件是围绕提供等待/通知功能的底层 Lock 的包装器。您需要先获取 一个锁,然后才能释放它 - wait 在后台执行此操作。值得注意的是,一旦它被重新唤醒,它就会重新获取锁。因此,在获取和释放之间确保了互斥,如果有意义的话,wait“让出”锁的控制权。

与其手动获取/释放,不如使用 Condition 作为上下文管理器:

def consumer(cond):
    with cond:
        cond.wait()

    logging.debug('Resource is available to consumer')

如果出于某种原因你被困在没有上下文管理器的 python 版本上,这等同于:

def consumer(cond):
    try:
        cond.acquire()
        cond.wait()
    finally:
        cond.release()

    logging.debug('Resource is available to consumer')

通常您希望确保只有一个消费者被唤醒,因此经常使用以下成语:

with cond:
    while some_queue.isEmpty():
        cond.wait()
    #get one from queue

因此,您可以通知任意数量的消费者,一旦队列为空,多余的消费者就立即返回休眠状态。

关于python - 线程条件变量 : un-acquired lock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23116383/

相关文章:

python - 如何在 numpy 中获得逐元素矩阵乘法(Hadamard 乘积)?

ios - NSMutableArray 集合和@Synchronized block

Java ForkJoinPool 线程未完成

python-3.x - 每当我在 CMD 中运行 pip -V 时,Windows 就会崩溃

python - 是否可以在管理员之外使用 django-modeltranslation?

python - ValueError at/无效格式字符串

python - CNN 返回相同的分类结果(keras)

c# - 向现有 WaitAll 添加更多任务

python - pandas DataFrame 中 bool 数组的按行求和

python - 为什么即使在关闭临时文件后我仍然可以写入和读取它?