线程池

作者: 拖延症旳理想主义者 | 来源:发表于2020-11-27 10:09 被阅读0次

模拟网页下载的任务

def get_page_html(seconds, url):
    # sleep模拟下载耗时
    time.sleep(seconds)
    logger.info(f"URL:{url}下载网页成功,耗时{seconds}秒")
    # 返回页面源码+耗时
    return url, seconds

实例化线程池,并提交下载任务

from concurrent.futures import ThreadPoolExecutor

# 实例化线程池,并指定线程池的容量
executor = ThreadPoolExecutor(max_workers=1)

# submit方法:向线程池中提交任务:函数名+参数列表
task_1 = executor.submit(get_page_html, 3, "http://3.com")
task_2 = executor.submit(get_page_html, 2, "http://2.com")

任务执行完成后,返回一个Future对象

# 未来对象,或者是任务执行结果的容器
class Future(object):
    """Represents the result of an asynchronous computation."""

Future对象里的常用方法

1、获取线程的执行状态

# 获取线程任务的执行状态
logger.info(f"task_1是否执行完毕: {task_1.done()}")
logger.info(f"task_2是否执行完毕: {task_2.done()}")

2、获取线程任务的执行结果

# 获取线程异步执行完成后的结果,这里会阻塞主线程,等待子线程的执行结果
logger.info(task_1.result())

result()是一个阻塞的方法

3、取消线程任务的执行

# 在线程未开启前,即没有进到线程池中前,可以关闭该线程任务
task_2.cancel()

4、添加回调函数

# 线程任务执行完成,可以指定回调函数,接受一个future作为参数
def callback(future):
    logger.info(future.result())
# 添加回调函数
task_1.add_done_callback(callback)

批量提交线程任务

# 实例化线程池对象
executor = ThreadPoolExecutor(max_workers=3)

# 使用列表生成器批量提交任务到线程池
all_task = [executor.submit(get_page_html, seconds, url) for seconds, url in [(1, "http://1"), (2, "http://2")]]

线程任务执行完毕后立即接收返回值

from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED

# as_completed是一个生成器,会把执行完成的Future yield回来
for future in as_completed(fs=all_task):
    logger.info(future.result())

等待线程任务全部执行完毕

# 主线程阻塞,等待所有子线程执行完毕
wait(all_task, return_when=ALL_COMPLETED)
logger.info("主线程执行完毕")

使用线程池执行Selenium程序

# _*_coding:utf-8_*_

"""
@Time   : 2020/11/27 10:10
@Author : CarpLi
@File   : thread_pool_selenium.py
@Desc   : 使用线程池启动Chrome访问百度
"""
import time
from loguru import logger
from concurrent.futures import ThreadPoolExecutor, as_completed
from selenium.webdriver import Chrome


# chrome浏览器访问url
def open_url_page(url):
    chrome = Chrome()
    chrome.get(url)
    time.sleep(2)
    title = chrome.title
    chrome.quit()
    return title


executor = ThreadPoolExecutor(max_workers=5)
all_task = [executor.submit(open_url_page, f"https://www.baidu.com/s?wd={url}") for url in range(1, 20)]

for future in as_completed(all_task):
    # 有线程任务执行成功就直接返回
    logger.info(future.result())


if __name__ == '__main__':
    pass

相关文章

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • Spring Boot之ThreadPoolTaskExecut

    初始化线程池 corePoolSize 线程池维护线程的最少数量keepAliveSeconds 线程池维护线程...

  • 线程池

    1.线程池简介 1.1 线程池的概念 线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • ThreadPoolExecutor线程池原理以及源码分析

    线程池流程: 线程池核心类:ThreadPoolExecutor:普通的线程池ScheduledThreadPoo...

  • 线程池

    线程池 [TOC] 线程池概述 什么是线程池 为什么使用线程池 线程池的优势第一:降低资源消耗。通过重复利用已创建...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

  • 线程池

    JDK线程池 为什么要用线程池 线程池为什么这么设计 线程池原理 核心线程是否能被回收 如何回收空闲线程 Tomc...

网友评论

      本文标题:线程池

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