首页 > 其他分享 >Day 17 17.3 多线程实现之线程池

Day 17 17.3 多线程实现之线程池

时间:2023-03-19 09:34:54浏览次数:39  
标签:17 img 17.3 线程 time print import 多线程 ThreadPoolExecutor

多线程实现之线程池

1 引入

  • 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。

    • 在这种情形下,使用线程池可以很好地提升性能,
    • 尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。
  • 线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。

    • 当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。
  • 此外,使用线程池可以有效地控制系统中并发线程的数量。

    • 当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

2 模块

  • 线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,
    • 即 ThreadPoolExecutor 和 ProcessPoolExecutor,
      • ThreadPoolExecutor 用于创建线程池,
      • ProcessPoolExecutor 用于创建进程池。

3 创建步骤

  • 使用线程池来执行线程任务的步骤如下:

    • 调用 ThreadPoolExecutor 类的构造器创建一个线程池。

    • 定义一个普通函数作为线程任务。

    • 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。

    • 调用 ThreadPoolExecutor 对象的 shutdown(wait = True) 方法来关闭线程池。

    def fun(index):
    	print(index)
    	time.sleep(3)
    	
    from concurrent.futures import ThreadPoolExecutor
    theard_pool = ThreadPoolExecutor(max_workers=2)
    for i in range(1000):
    	thread_pool.submit(fun, i)
    thread_pool.shutdown(wait= True)
    
import time
from concurrent.futures import ThreadPoolExecutor


def task(i):
    print(f'任务{i}开始!')
    time.sleep(i)
    print(f'任务{i}结束!')
    return i


start = time.time()
pool = ThreadPoolExecutor(3)

future01 = pool.submit(task, 1)
# print("future01是否结束", future01.done())
# 当程序使用 Future 的 result() 方法来获取结果时,该方法会阻塞当前线程,如果没有指定 timeout 参数,当前线程将一直处于阻塞状态,直到 Future 代表的任务返回。
# print("future01的结果", future01.result())  # 同步等待
future02 = pool.submit(task, 2)
future03 = pool.submit(task, 3)
pool.shutdown()  # 阻塞等待
print(f"程序耗时{time.time() - start}秒钟")

print("future01的结果", future01.result())
print("future02的结果", future02.result())
print("future03的结果", future03.result())

使用线程池来执行线程任务的步骤如下:

  1. 调用 ThreadPoolExecutor 类的构造器创建一个线程池。
  2. 定义一个普通函数作为线程任务。
  3. 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。
  4. 当不想提交任何任务时,调用 ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程池。

4 应用案例

import requests
from lxml import etree
import os
import asyncio
import time
import threading


def get_img_urls():
    res = requests.get("https://www.pkdoutu.com/photo/list/", headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
    })
    
    selector = etree.HTML(res.text)
    img_urls = selector.xpath('//li[@class="list-group-item"]/div/div/a/img[@data-backup]/@data-backup')

    print(img_urls)
    return img_urls


def save_img(url):
    res = requests.get(url)
    name = os.path.basename(url)
    with open("imgs/" + name, "wb") as f:
        f.write(res.content)
    print(f"{name}下载完成!")


def main():
    img_urls = get_img_urls()
    # 串行
    [save_img(url) for url in img_urls]
    # 协程并发
    t_list = []
    for url in img_urls:
        t = threading.Thread(target=save_img, args=(url,))
        t.start()
        t_list.append(t)

    for t in t_list:
        t.join()


if __name__ == '__main__':
    start = time.time()
    main()
    end = time.time()
    print(end - start)

针对IO密集型任务,Python多线程可以发挥出不错的并发作用

标签:17,img,17.3,线程,time,print,import,多线程,ThreadPoolExecutor
From: https://www.cnblogs.com/dream-ze/p/17232465.html

相关文章

  • java学习日记20230317-多态
    多态方法和对象爱过你具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承的基础上;方法的重载体现多态方法的重写体现多态对象的多态一个对象的编译类型和......
  • 3月17日总结
    includeusingnamespaceQtDataVisualization;intmain(intargc,char**argv){QGuiApplicationapp(argc,argv);Q3DScatterscatter;scatter.setFlags(scatter.f......
  • 多线程编程五:信号量
    2.33.信号量的概念_哔哩哔哩_bilibili2.34.信号量的工作机制_哔哩哔哩_bilibili......
  • 每日总结--2023/3/17
    课程:计算机网络概率论web学习内容:完成了一个个人介绍的web页面及实验报告继续学习了数据链路层的相关内容完成了每日打卡app记录时间的功能 ......
  • day17
    day17可变参数就是说一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称可变参数的1特点与好处特点:可以不传数据给它,可以传一个或者同时多个数......
  • 20230317软件测试入门
    https://zh.wikipedia.org/wiki/软件测试https://www.ibm.com/cn-zh/topics/software-testinghttps://www.softwaretestingmaterial.com/software-testing/https......
  • 多线程基础
     基本概念:程序、进程、线程程序(program):为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。进程(process):是指一个内存中运行......
  • c++ 影响多线程速度的因素记录
    目录0.序言1.缓存行同步问题/共享数据竞争1.1测试代码1.2测试逻辑1.3测试结果1.4小结2.任务颗粒度过小问题2.1测试代码2.1测试逻辑2.2测试结果2.3小结3.缓存未......
  • 3.17双人总结
    import java.util.LinkedList;public class Graph { public int num;                     //结点总数 /*  * LinkedList<Integer> adj[] ......
  • 日程报告17
    因为AndroidStudio4.1.3用起来实在是太不方便了,所以在今天我卸载了AndroidStudio,重新下载了最新版本说实话,我已经做好面对一堆报错的准备了,但是这一次他神奇的没有任......