0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

python创建线程池的两种方法

python爬虫知识分享 来源:python爬虫知识分享 作者:python爬虫知识分享 2022-03-16 16:15 次阅读

1. 使用内置模块

在使用多线程处理任务时也不是线程越多越好,由于在切换线程的时候,需要切换上下文环境,依然会造成cpu的大量开销。为解决这个问题,线程池的概念被提出来了。预先创建好一个合理数量的线程池,让过来的任务立刻能够使用,就形成了线程池。

Python3中,创建线程池是通过concurrent.futures函数库中的ThreadPoolExecutor类来实现的。

import time
import threading
from concurrent.futures import ThreadPoolExecutor

def target():
    for i in range(5):
        print('running thread-{}:{}'.format(threading.get_ident(), i))
        time.sleep(1)

# 创建一个最大容纳数量为5的线程池
pool = ThreadPoolExecutor(5)

for i in range(10):
    # 往线程池上塞任务
    pool.submit(target)

创建线程池还可以使用更优雅的方式,就是使用上下文管理器

with ThreadPoolExecutor(5) as pool:
    for i in range(100):
        pool.submit(target)

直接运行代码,从输出可以看出,前面我们设置线程池最大线程数,会保证“同时”仅有五个线程在工作。

running thread-123145483767808:0
running thread-123145489022976:0
running thread-123145494278144:0
running thread-123145499533312:0
running thread-123145504788480:0
running thread-123145483767808:1
running thread-123145489022976:1
running thread-123145499533312:1
running thread-123145494278144:1
running thread-123145504788480:1
running thread-123145489022976:2
running thread-123145499533312:2
running thread-123145483767808:2
running thread-123145504788480:2
running thread-123145494278144:2
....

示例完毕,来说明一下:

使用 with 语句 ,通过 ThreadPoolExecutor 构造实例,同时传入 max_workers 参数来设置线程池中最多能同时运行的线程数目。

使用 submit 函数来提交线程需要执行的任务到线程池中,并返回该任务的句柄(类似于文件、画图),注意 submit() 不是阻塞的,而是立即返回。

通过使用 done() 方法判断该任务是否结束。上面的例子可以看出,提交任务后立即判断任务状态,显示四个任务都未完成。在延时2.5后,task1 和 task2 执行完毕,task3 仍在执行中。

使用 result() 方法可以获取任务的返回值。

2. 自定义线程池

除了使用上述第三方模块的方法之外,我们还可以自己结合前面所学的消息队列来自定义线程池。

这里我们就使用queue来实现一个上面同样效果的例子,大家感受一下。

import time
import threading
from queue import Queue

def target(queue):
    while True:
        task = queue.get()
        if task == "stop":
            queue.task_done()
            break

        task()
        queue.task_done()

def do_task():
    for i in range(5):
        print('running thread-{}:{}'.format(threading.get_ident(), i))
        time.sleep(1)


class MyQueue(Queue):
    def close(self):
        for i in range(self.maxsize):
            self.put("stop")

def custome_pool(task_func, max_workers):
    queue = MyQueue(max_workers)
    for n in range(max_workers):
        t = threading.Thread(target=task_func, args=(queue,))
        t.daemon = True
        t.start()

    return queue



pool = custome_pool(task_func=target, max_workers=5)

for i in range(10):
    pool.put(do_task)

pool.close()
pool.join()

输出是和上面是完全一样的效果

running thread-123145469886464:0
running thread-123145475141632:0
running thread-123145485651968:0
running thread-123145490907136:0
running thread-123145480396800:0
running thread-123145469886464:1
running thread-123145480396800:1
running thread-123145475141632:1
running thread-123145490907136:1
running thread-123145485651968:1
...

构建线程池的方法,是可以很灵活的,大家有空可以自己多研究。但是建议只要掌握一种自己熟悉的,能快速上手的就好了。
审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2750

    浏览量

    48154
  • 函数
    +关注

    关注

    3

    文章

    4353

    浏览量

    63292
  • python
    +关注

    关注

    56

    文章

    4813

    浏览量

    85301
收藏 人收藏

    评论

    相关推荐

    请问如何在Python中实现多线程与多进程的协作?

    大家好!我最近在开发一个Python项目时,需要同时处理多个任务,且每个任务需要不同的计算资源。我想通过多线程和多进程的组合来实现并发,但遇到了一些问题。 具体来说,我有个任务,一个是I/O密集型
    发表于 03-11 06:57

    创建了用于OpenVINO™推理的自定义C++和Python代码,从C++代码中获得的结果与Python代码不同是为什么?

    创建了用于OpenVINO™推理的自定义 C++ 和 Python* 代码。 在个推理过程中使用相同的图像和模型。 从 C++ 代码中获得的结果与 Python* 代码不同。
    发表于 03-06 06:22

    Python中多线程和多进程的区别

    Python作为一种高级编程语言,提供了多种并发编程的方式,其中多线程与多进程是最常见的两种方式之一。在本文中,我们将探讨Python中多线程
    的头像 发表于 10-23 11:48 610次阅读
    <b class='flag-5'>Python</b>中多<b class='flag-5'>线程</b>和多进程的区别

    比较分析两种不同的可提高栅极驱动电流的方法

    电子发烧友网站提供《比较分析两种不同的可提高栅极驱动电流的方法.pdf》资料免费下载
    发表于 09-23 11:13 0次下载
    比较分析<b class='flag-5'>两种</b>不同的可提高栅极驱动电流的<b class='flag-5'>方法</b>

    买药秒送 JADE动态线程实践及原理浅析

    一、背景及JADE介绍 买药秒送是健康即时零售业务新的核心流量场域,面对京东首页高流量曝光,我们对频道页整个技术架构方案进行升级,保障接口高性能、系统高可用。 动态线程是买药频道应用的技术之一
    的头像 发表于 09-04 11:11 950次阅读
    买药秒送 JADE动态<b class='flag-5'>线程</b><b class='flag-5'>池</b>实践及原理浅析

    linux驱动程序的编译方法有哪两种

    Linux驱动程序的编译方法主要可以归纳为两种: 手动编译 和 使用内核构建系统(Makefile)自动编译 。 1. 手动编译 手动编译驱动程序通常涉及直接使用GCC(GNU Compiler
    的头像 发表于 08-30 14:39 1083次阅读

    利用Python脚本登录到交换机并创建VLAN

    本文将详细介绍如何利用Python脚本登录到交换机并创建VLAN。
    的头像 发表于 08-12 17:59 706次阅读

    rtt工程移植后线程创建不成功怎么解决?

    之前用l431的板子跑10k的采样后来要提高到100k,更换了f446的芯片,但是根据新的内存地址从0x20000000开始写入数据后,线程创建不成功了,不知道是否是线程的的大小不
    发表于 07-18 06:44

    探索虚拟线程:原理与实现

    虚拟线程的引入与优势 在Loom项目之前,Java虚拟机(JVM)中的线程是通过java.lang.Thread类型来实现的,这些线程被称为平台线程。 然而,平台
    的头像 发表于 06-24 11:35 411次阅读
    探索虚拟<b class='flag-5'>线程</b>:原理与实现

    鸿蒙开发:【线程模型】

    管理其他线程的ArkTS引擎实例,例如使用TaskPool(任务创建任务或取消任务、启动和终止Worker线程
    的头像 发表于 06-13 16:38 511次阅读
    鸿蒙开发:【<b class='flag-5'>线程</b>模型】

    动态线程思想学习及实践

    相关文档 美团线程实践:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 线程思想解
    的头像 发表于 06-13 15:43 1308次阅读
    动态<b class='flag-5'>线程</b><b class='flag-5'>池</b>思想学习及实践

    数字设备中采集数字图像的两种方法是什么

    在数字设备中,采集数字图像的方法有很多种,但最常见的两种方法是:1) 使用数字相机拍摄,2) 通过扫描仪扫描。 一、使用数字相机拍摄 数字相机是一种可以捕捉图像并将其转换为数字格式的设备。数字相机
    的头像 发表于 05-31 15:48 1042次阅读

    使用FreeRTOS创建的DHCP线程里面的DHCP是在哪里定义的?

    请教下,使用 FreeRTOS 创建的 DHCP 线程里面的 DHCP 是在哪里定义的,貌似没有找到 ? FreeRTOS 版本 v9.0.0 具体如下: // 创建 DHCP 线程
    发表于 04-30 07:34

    OpenHarmony语言基础类库【@ohos.taskpool(启动任务)】

    任务(taskpool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且您无需关心线程实例的生命周期。您可以使用任务API
    的头像 发表于 04-24 17:45 444次阅读
    OpenHarmony语言基础类库【@ohos.taskpool(启动任务<b class='flag-5'>池</b>)】

    java实现多线程的几种方式

    的CompletableFuture 一、继承Thread类 继承Thread类是实现多线程的最基本方式,只需创建一个类并继承Thread类,重写run()方法即可。 ``
    的头像 发表于 03-14 16:55 851次阅读