Python使用ThreadPoolExecutor线程池和Queue消息队列

Python使用ThreadPoolExecutor线程池和Queue消息队列

1 介绍

(1)线程池

concurrent.futures模块是从 Python3.2 后引入的异步执行模块,主要用于在多核CPU和网络I/O中进行高效的并发编程。这个模块提供了ThreadPoolExecutor(线程池)和ProcessPoolExecutor(进程池)两个类。

可使用concurrent.futures.ThreadPoolExecutor直接创建线程池,需要设置最大的线程数,用submit()执行线程。

(2)消息队列

Python中的Queue是线程安全的消息队列,可使用queue.Queue完成消息队列。

put()和get()配合使用,可使用put()创建消息,使用get()消费消息,使用qsize()获取消息长度。

join()和task_done()配合使用,join()用于阻塞调用线程,直到队列中的所有任务被处理掉;task_done()用于通知队列任务已完成,每一个由put()调用入队的任务都有一个对应的task_done()调用。一般在使用join()阻塞线程时才会使用task_done()。

2 代码

import random
from concurrent.futures import ThreadPoolExecutor
from queue import Queue
from threading import Lock
from time import sleep

# 创建线程池
# max_workers:最大线程池的数量
max_workers = 3
executor = ThreadPoolExecutor(max_workers=max_workers)


# 添加锁
lock = Lock()

# 构建消息队列,Queue是线程安全的
queue_task = Queue()

# 数据库(假设)
db_record = list()


def run_task(msg):
    # 添加消息
    queue_task.put(msg)

    if queue_task.qsize() > max_workers:
        return

    # 执行线程池
    executor.submit(doing_task)


def doing_task():

    # 消费消息队列中的任务
    while queue_task.qsize() > 0:
        # 获取消息
        msg = queue_task.get()
        print("start-" + str(msg))

        # 跟新数据库(假设)
        # 添加锁
        lock.acquire()

        # 更新
        db_record.append(msg)

        # 释放锁
        lock.release()

        # 随机睡眠1-3秒
        sleep(random.randint(1, 3))

        print("end-" + str(msg))


if __name__ == '__main__':
    run_task(1)
    run_task(2)
    run_task(3)
    run_task(4)
    run_task(5)
    run_task(6)

Python的`concurrent.futures`模块是Python标准库中的一个异步执行工具,它提供了两个高级API:`ThreadPoolExecutor``ProcessPoolExecutor`,分别用于实现线程池进程池。线程池可以用来管理一组工作线程,可以提交任务给这些工作线程执行,并且可以控制这些工作线程的并发数量。队列则是用来在工作线程之间传递数据的。 当你想要组合使用线程池队列时,可以利用`ThreadPoolExecutor`中的`submit`方法提交任务到线程池,而任务函数中则可以使用队列来获取或发送数据。这种方式在多线程环境下处理数据时非常有用,因为它可以安全地在多个线程之间共享数据,而不需要担心线程安全问题。 下面是一个简单的示例: ```python from concurrent.futures import ThreadPoolExecutor, as_completed from queue import Queue # 定义一个任务函数,它从队列中取出任务并处理 def worker(task_queue): while not task_queue.empty(): # 从队列中获取任务 task = task_queue.get() # 进行处理 print(f"Processing {task}") # 告知队列任务处理完成 task_queue.task_done() # 创建一个任务队列 task_queue = Queue() # 向队列中添加一些任务 for i in range(5): task_queue.put(f"Task {i}") # 创建线程池 with ThreadPoolExecutor(max_workers=3) as executor: # 将任务分配给线程池处理 for _ in range(task_queue.qsize()): executor.submit(worker, task_queue) # 等待所有任务完成 task_queue.join() print("所有任务处理完毕") ``` 在这个示例中,我们首先创建了一个任务队列,并向队列中添加了一些任务。然后创建了一个线程池,并将工作线程提交给线程池来执行`worker`函数,该函数会从队列中取出任务并进行处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值