📜  Python中使用 Condition() 方法的线程间通信(1)

📅  最后修改于: 2023-12-03 15:19:23.092000             🧑  作者: Mango

Python中使用 Condition() 方法的线程间通信

在Python的多线程编程中,线程间的通信是很常见的需求。Python 提供了 Condition 类,能够允许线程等待某些条件发生后再进行操作,以实现线程间的同步。

Condition类和方法

Condition 类实现了一个条件变量,它能够通过wait()、notify()和notify_all()等方法实现线程间的协调。

  • wait([timeout]): 线程在等待信号的时候会被阻塞,直到接收到notify()或notify_all()信号或者超时,可以设置超时时间。
  • notify(n=1): 通知正在等待此条件变量的某个线程(如果有多个,则任选一个)可以开始执行。
  • notify_all(): 通知所有正在等待此条件变量的线程执行。
实例

下面是一个例子,模拟了生产者-消费者模式,使用线程的Condition类实现。

import threading
import time

# 定义一个共享的buffer
shared_buffer = []
# 定义Condition对象
buffer_lock = threading.Condition()

# 生产者线程
class ProducerThread(threading.Thread):
    def run(self):
        global shared_buffer
        while True:
            buffer_lock.acquire()
            if len(shared_buffer) >= 10:
                print("Buffer is full, producer is waiting")
                buffer_lock.wait() # 线程在此等待
            else:
                shared_buffer.append(1)
                print("Added 1 to buffer, buffer length is", len(shared_buffer))
            buffer_lock.notify_all() # 通知所有线程
            buffer_lock.release()
            time.sleep(1)

# 消费者线程
class ConsumerThread(threading.Thread):
    def run(self):
        global shared_buffer
        while True:
            buffer_lock.acquire()
            if len(shared_buffer) == 0:
                print("Buffer is empty, consumer is waiting")
                buffer_lock.wait() # 线程在此等待
            else:
                shared_buffer.pop(0)
                print("Removed 1 from buffer, buffer length is", len(shared_buffer))
            buffer_lock.notify_all() # 通知所有线程
            buffer_lock.release()
            time.sleep(1)

# 创建线程实例,启动线程
ProducerThread().start()
ConsumerThread().start()

在这个例子中,当buffer满时,生产者线程调用wait()方法陷入等待,而在其他时刻,线程会调用notify_all()方法通知所有等待的线程。消费者线程同样在 buffer 为空时调用 wait() 方法陷入等待。一旦数据在buffer内,消费线程通过调用 notify_all() 方法来唤醒所有的线程。

通过这种方式,我们可以让不同的线程在特定的条件下等待,以达到线程之间的同步和协调。

小结

Python 的 Condition 类是一种使用很方便的工具,它可以用于多线程编程中的线程间通信。通过lock+condition可以实现更加复杂的同步,不仅仅是生产者-消费者模式,还有其他的例子,可以从中获取灵感。但是也应该注意,如果不小心使用,使用Condition还可能导致死锁。