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

    文章

    2822

    浏览量

    52817
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66863
  • python
    +关注

    关注

    57

    文章

    4858

    浏览量

    89612
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux多线程对比单线程的优势

    的示例代码,创建三个线程,每个线程实现不同的任务:#include #include void *task1(void *arg) { printf(\"Thread 1
    发表于 12-01 06:11

    用PLC实现卷径计算的两种算法

    卷径计算,是动态计算如钢卷,纸卷等存料量的一种方法,它是实现张力控制和自动充放料、以及甩尾控制的重要前提。卷径计算目前主流的方法两种,一种是根据机列速度(产线速度)和和被测卷的转动角速度求得;另一种是根据被测卷的转动圈数和测长
    的头像 发表于 11-14 16:54 1415次阅读
    用PLC实现卷径计算的<b class='flag-5'>两种</b>算法

    有多少种方法可以进行频响曲线测量?

    APx500软件提供了频响曲线的多种测量方法,对一个音频产品的频响特性进行测量分析。如果只用一个测量对一个音频产品进行评价,那这个测量就是频响曲线,APx500软件提供了多种方法可以进行频响曲线测量
    的头像 发表于 11-14 11:29 329次阅读
    有多少<b class='flag-5'>种方法</b>可以进行频响曲线测量?

    RTThread线程退出后rt_malloc动态创建的资源没有释放怎么解决?

    测试过程中,在一个线程中用rt_malloc动态创建4KB的资源,在线程运行过程中用rt_thread_delete()使线程退出,用memtrace查看内存分配情况,动态
    发表于 10-13 07:06

    线程问题,线程已经创建成功了,为什么线程调用的函数不会运行呢?

    我这个线程创建成功了,为啥ai_thread_entry()函数不运行呢? void airun_thread() { /* 创建 serial 线程 */ rt_thread_
    发表于 10-10 08:02

    RT-Thread Nano移植后动态创建线程创建不了怎么解决?

    RT-Thread Nano 移植后动态创建线程创建不了,静态可以.直接烧录DEMO也一样,将RT_USING_HEAP开起来,使用动态创建创建
    发表于 09-19 06:28

    rtth studio中nano 如何创建动态线程

    有没有大佬,可以说一下为什么静态线程可以正常使用,动态线程怎么也使用不了。 具体需要什么配置才能使用动态线程创建。谢谢!
    发表于 09-11 06:01

    【HZ-T536开发板免费体验】—— linux创建线程

    的执行任务成为单线程。多线程是程序中包含多个执行流,在一个程序中可以同时运行多个不同的线程来执行不同的任务。 多线程提高了CPU的使用卤率。多线程
    发表于 09-01 21:31

    rtt studio中nano 如何创建动态线程

    有没有大佬,可以说一下为什么静态线程可以正常使用,动态线程怎么也使用不了。 具体需要什么配置才能使用动态线程创建。谢谢!
    发表于 08-22 06:19

    如何移植 RT-Thread Nano 并创建 2 个线程

    基于 BSP 中的 GPIO_OutputInput 演示,展示了如何移植 RT-Thread Nano 并创建 2 个线程
    发表于 08-19 07:45

    RT-Thread Nano移植后动态创建线程创建不了怎么处理?

    RT-Thread Nano移植后动态创建线程创建不了,静态可以.直接烧录DEMO也一样,将RT_USING_HEAP开起来,使用动态创建创建
    发表于 06-11 06:36

    六相永磁同步电机串联系统控制的两种方法分析研究

    /simulink环境下,分别用这两种方法台电机串联系统的运行特性进行仿真研究。当其中一台电机转速、负载变化时,分析两种方法下另外一台电机独立运行的情况,脸证分析这两种方法的可行性
    发表于 06-10 13:09

    进程、线程、协程傻傻分不清?一文带你彻底扒光它们的\"底裤\"!

    保存寄存器和栈指针(就像你下班时关灯、锁门) 死锁风险:线程同时抢最后一块披萨(资源竞争) 职场类比: **奶茶店有3个员工(3个线程): 收银员(线程A):负责下单 制作员(
    发表于 03-26 09:27

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

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

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

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