天天看点

pyhon3 queue模块生产者消费者模式、线程池功能在多线程应用示例

作者:运维木子李

Python的queue模块提供了线程安全的队列数据结构,用于在多线程环境下进行线程间的安全数据传递和协调。它实现了线程安全的生产者消费者模式,具有阻塞和非阻塞的操作方法,适用于各种多线程场景。下面分别说明queue模块在多线程下的功能和应用场景,并给出示例:

queue模块在多线程下的功能:

  • 线程安全:queue模块提供了线程安全的队列数据结构,多个线程可以同时访问和操作队列,而不需要自己实现线程同步。
  • 阻塞操作:queue模块中的队列类提供了阻塞操作方法,当队列为空时,消费者线程可以阻塞等待新的数据;当队列满时,生产者线程可以阻塞等待队列有可用空间。
  • 非阻塞操作:queue模块中的队列类还提供了非阻塞的操作方法,可以立即返回结果,不会阻塞线程。

queue模块的应用场景:

  • 生产者消费者模式:可以使用队列作为生产者和消费者之间的缓冲区,实现线程间的安全数据传递和协调。
  • 线程池:可以使用队列来实现线程池中的任务队列,将任务提交到队列中,由工作线程从队列中获取任务进行处理。
pyhon3 queue模块生产者消费者模式、线程池功能在多线程应用示例

示例1:生产者消费者模式

import threading
import queue
import time

# 创建一个队列对象
q = queue.Queue()

# 生产者线程
def producer():
    for i in range(5):
        time.sleep(1)  # 模拟生产数据的耗时操作
        data = f"Data {i}"
        q.put(data)
        print(f"Producer put data: {data}")

# 消费者线程
def consumer():
    while True:
        data = q.get()
        print(f"Consumer get data: {data}")
        q.task_done()  # 标记任务为已完成

# 创建并启动线程
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
producer_thread.start()
consumer_thread.start()

# 等待生产者线程完成所有数据的生产
producer_thread.join()

# 阻塞等待队列中的任务完成
q.join()

# 终止消费者线程
consumer_thread.join()           

在上述示例中,我们创建了一个队列对象q。生产者线程通过q.put()方法向队列中生产数据,消费者线程通过q.get()方法从队列中消费数据。通过q.task_done()方法标记任务为已完成,以便主线程可以阻塞等待队列的任务全部完成。

示例2:线程池

import threading
import queue

# 创建一个队列对象
q = queue.Queue()

# 工作线程函数
def worker():
    while True:
        task = q.get()
        if task is None:
            break
        # 处理任务
        print(f"Worker processing task: {task}")
        q.task_done()

# 创建并启动线程池
num_workers = 4
threads = []
for _ in range(num_workers):
    thread = threading.Thread(target=worker)
    thread.start()
    threads.append(thread)

# 添加任务到队列
for i in range(10):
    q.put(f"Task {i}")

# 阻塞等待队列中的任务完成
q.join()

# 终止工作线程
for _ in range(num_workers):
    q.put(None)

# 等待工作线程退出
for thread in threads:
    thread.join()           

在上述示例中,我们创建了一个队列对象q作为任务队列。工作线程通过q.get()方法从队列中获取任务进行处理,通过q.task_done()方法标记任务为已完成。主线程将任务添加到队列中,通过q.join()方法阻塞等待队列的任务全部完成。

这些示例展示了queue模块在多线程下的功能和应用场景。通过使用队列,可以实现线程间的安全数据传递和协调,提高多线程程序的效率和性能。

继续阅读