美文网首页
Python多线程(五):线程池

Python多线程(五):线程池

作者: NWKYEKJ | 来源:发表于2019-03-15 11:09 被阅读0次

上一篇:生产者消费者问题

在之前的文章中我们一般只演示了两个线程的情况,在实际中我们要管理多个线程的时候就需要用到线程池。使用线程池管理线程能够使主线程可以获得某一线程的状态以及返回值,当一个线程完成的时候主线程就能立知道。

这里我们使用的线程池类是ThreadPoolExecutor,它在concurrent.futures下。concurrent.futures中还包括了ProcessPoolExecutor进程池对象,这个包的设计让多线程和多进程的接口一致。

下面是一个例子:

from concurrent.futures import ThreadPoolExecutor
import time

def do_something(name, sec):
    print('Start doing %s' % name)
    time.sleep(sec)
    print('%s completed' % name)
    return name

executor = ThreadPoolExecutor(max_workers=2)
task = executor.submit(do_something, 'A', 2)
print(task.done())
print(task.result())
print(task.done())

运行结果:

Start doing A
False
A completed
A
True

首先需要实例化一个线程池对象,ThreadPoolExecutor类包含一个参数max_workers,表示最大同时运行的线程个数。线程池中可以田间任意多个线程,但是同时能运行的个数为max_workers,其他线程需要等当前正在运行的max_workers个线程运行完成才能运行。线程池对象的submit方法可传入一个函数句柄及它的参数,参数依次排列。一旦调用submit方法,线程就已经开始执行或即将执行,并返回一个Future对象。可调用Future对象的done方法查看线程是否执行完成,该方法非阻塞。还可以调用result方法获得线程的返回值,该方法阻塞直到线程结束得到返回值。

如果线程过多,可采用下面的写法:

from concurrent.futures import ThreadPoolExecutor, as_completed
import random
...

all_task = [executor.submit(do_something, 'task_%d' %i, random.uniform(2,6)) for i in range(10)]
for future in as_completed(all_task):
    data = future.result()
    print(data)

这里的as_completed是一个生成器,它会生成已经完成的线程的future对象。先执行完成的线程的future对象会先被生成,直到所有线程结束,最后一个线程的future对象被生成。从结果来看,由于每次的线程切换不同,执行结果也不同。

另外还可以用ThreadPoolExecutor对象的map方法查询线程是否执行完成:

for data in executor.map(do_something, ['task_%d' %i for i in range(10)], [random.uniform(2,6) for i in range(10)]):
    print(data)

和之前的as_completed方法不同,map生成器是按照参数的顺序返回的,但是线程执行依然是无序的。而且map返回的是线程的返回值,不是Future对象。在实践中最常用的还是第一种方法。

concurrent.futures还提供了wait方法,用于阻塞主线程。其用法是:

from concurrent.futures import wait, ALL_COMPLETED, FIRST_COMPLETED, FIRST_EXCEPTION
wait(fs=all_task, return_when=ALL_COMPLETED)

第一参数fs是需要等待的线程列表,还有一个可选参数是return_when,即停止阻塞的条件,默认是ALL_COMPLETED,即所有线程完成。除此之外还包括:FIRST_COMPLETED(第一个线程执行完成后)、FIRST_EXCEPTION(在子线程中第一次出现抛出错误后)。

相关文章

  • Python多线程(五):线程池

    上一篇:生产者消费者问题 在之前的文章中我们一般只演示了两个线程的情况,在实际中我们要管理多个线程的时候就需要用到...

  • Springboot | 线程池的学习,多线程池配置示例

    一、线程和进程,线程的生命周期二、单线程和多线程三、线程池的概念四、线程池的使用五、多线程池配置示例 一、线程和进...

  • Python多线程

    目录:一、线程的创建二、多线程互斥锁三、线程间通信四、线程池 Python并发之多线程 一、线程的创建 单线程示例...

  • Thread

    队列 线程锁 多线程,线程池 队列 多线程爬虫示例 多线程 自定义线程 线程池

  • [Python系列]Python多线程

    背景:说到多线程,我们会想到的是:异步编程、同步(锁)、共享变量、线程池等等,那么Python里面多线程是如何实现...

  • Java:线程池Executors.newFixedThread

    摘要:Java,多线程,线程池 多线程编程和线程池概述 (1)多线程程序: 计算机可以实现多任务 ( multit...

  • Python多线程爬取王者荣耀COS小姐姐图片集

    多线程爬取数据,主要是用Python的线程池ThreadPoolExecutor。主要代码如下: 爬取到的资源如下...

  • 10.3多线程详解

    Java高级-多线程 多线程创建 多线程通讯 线程池 1.多线程创建 thread/runnable图:继承Thr...

  • python之多线程与多进程入门

    python之多线程与多进程 关键词: GIL锁,IO繁忙,线程安全,线程同步,进程池,进程通信,队列 GIL锁;...

  • Python并发编程——多线程

    摘要:Python,多线程,线程同步,线程池,GIL 线程概述 当一个进程里面只有一个线程时,叫做单线程,超过一个...

网友评论

      本文标题:Python多线程(五):线程池

      本文链接:https://www.haomeiwen.com/subject/lwtlmqtx.html