Python3之并发(六)---线程池

摘要:
余额不足!
一、线程池

系统频繁的启动新线程,线程执行完被销毁,如果线程不能被重复使用,即每个线程都需要经过启动、销毁和运行3个过程,
这必然会使得系统的性能急剧下降,线程池的意义就在于减少线程创建及消毁过程中损失的系统资源

线程池在程序运行时创建大量空闲线程,程序只需将要执行的任务交给线程池,线程池就会启动一个空闲的线程来执行,
当任务执行完后,该线程并不会死亡销毁,而是再次返回到线程池中变成空闲状态,等待一下次被启动

二、concurrent.futures模块
concurrent.futures.Executor类
线程池的基类,不应该直接使用该基类,通过其具体子类使用

EXecutor类包含两个子类

concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())
用于创建线程池
max_workers: 线程池中线程的个数,Python3.8版本中,默认min(32, os.cpu_count()+4)
thread_name_prefix: Python3.6版新增的参数,线程池中启动线程的名字
initializer,initargs: Python3.7版中新增的参数,初始化线程池的程序和要传入程序的参数


concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=())
用于创建进程池
max_workers: 进程池中进程的个数,默认处理器的个数
mp_context: Python3.7版中新增的参数,允许用户控制进程池中进程的start_method
initializer,initargs: 初始化线程池的程序和要传入程序的参数

线程池对象方法

ThreadPoolExecutor.submit(fn, *args, **kwargs)
线程池执行的任务,返回可调用的 Future 对象
fn: 线程池要执行的函数
*args: 传递给fn函数的参数
**kwargs: 关键字形式传递给fn函数的参数

ThreadPoolExecutor.map(func, *iterables, timeout=None, chunksize=1)
类似于 map(func, *iterables) 函数,启动多个线程以异步方式对 iterables 执行 func
timeout: 超时时间,int或float类型,超时引发 concurrent.futures.TimeoutError 异常

ThreadPoolExecutor.shutdown(wait=True)
关闭线程池,不再接收新线程任务,关闭后调用 submit() 和map() 引发 RuntimeError 异常
wait: 默认True,执行完所有线程后在关闭线程池;False表示立即关闭线程池,但是线程还是可以执行

Future对象的方法

Future类封装了一个可调用的异步执行结果对象,Future对象由 submit() 方法创建

Future.cancel()
取消当前Future代表的线程任务
若当前任务正在执行,无法取消,返回 False,否则,该任务被取消并且返回 True

Future.cancelled()
当前Future代表的线程任务被成功取消返回 True

Future.running()
当前Future代表的线程任务正在执行,无法取消,返回 Ture

Future.done()
当前Future代表的线程任务被取消或完成返回 True

Future.result(timeout=None)
返回当前Future代表的线程任务执行的结果
timeout: 等待当前Future代表的线程任务执行结果的最大超时时间,int或float类型,默认None,永不超时;若超时,引发 concurrent.futures.TimeoutError 异常

Future.exception(timeout=None)
返回当前Future代表的线程任务执引发的异常,如没有引发任何异常,返回 False
timeout: 等待当前Future代表的线程任务执行结果的最大超时时间,int或float类型,默认None,永不超时;若超时,引发 concurrent.futures.TimeoutError 异常

Future.add_done_callback(fn)
当前Future代表的线程任务被取消或者完成,执行的函数

示例

import threading
from concurrent.futures import ThreadPoolExecutor

#账户类
class Account:
    def __init__(self, account_no, balance):
        #账户编号和账户余额
        self.account_no = account_no
        self.balance = balance

        self._flag = False
        self.cond = threading.Condition()
    
    def getBlance(self):
        return self.balance
    
    #提取现金方法
    def draw(self, draw_amount):
        with self.cond:
            if not self._flag:
                self.cond.wait()
            else:
                if self.balance >= draw_amount:
                    print(threading.current_thread().name+'	取钱成功!吐出钞票:'+str(draw_amount))
                    self.balance -= draw_amount
                    print(threading.current_thread().name+'操作之后	余额为:'+str(self.balance))
                else:
                    print(threading.current_thread().name+'	取钱失败!余额不足!	当前余额为:'+str(self.balance))
                self._flag = False
                self.cond.notify_all()

    #存钱方法
    def deposit(self, deposit_amount):
        with self.cond:
            if  self._flag:
                self.cond.wait()
            else:
                print(threading.current_thread().name+'	存钱成功!存入钞票:'+str(deposit_amount))
                self.balance += deposit_amount
                print(threading.current_thread().name+'操作之后	余额为:'+str(self.balance))
                self._flag = True
                self.cond.notify_all()

acct = Account('986623', 1000)

with ThreadPoolExecutor(100, thread_name_prefix='Account_Thread_Pool') as pools:
    for i in range(50):
        pools.submit(acct.deposit, 1000)
        pools.submit(acct.draw, 900)

免责声明:文章转载自《Python3之并发(六)---线程池》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ethtool命令4006701855苹果开发者热线停止使用后如何联系苹果客服入口介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python多线程----线程池以及线程实现异步任务

Python多线程----线程池 需求:假设我们现在有一个多线程项目,每有一个用户连接进来,我们的服务器就会创建一个线程。而我们的服务器最多能够承载100个线程,再多就会崩溃。为了防止恶意用户伪装真实用户构建大量的访问来让我们的服务器崩溃,现在需要对线程数量进行限制,一共只有100个线程,并且当一个用户访问结束以后线程会自动归还,等待下一个用户访问。如果1...

TextRecognitionDataGenerator官方文档解读

Github地址: https://github.com/Belval/TextRecognitionDataGenerator 官方文档:https://textrecognitiondatagenerator.readthedocs.io/en/latest/index.html 官方文档解读 TextRecognitionDataGenerator’...

pyspider安装使用遇到的坑

一、pip install pyspider 安装出现错误: Command "python setup.py egg_info" failed with error code 10 in C:UsersxxxAppDataLocalTemppip-install-tc5uvu7lpycurl  经过网上大拿的经验需要安装wheel,执行命令pip3 in...

python3的leetcode题,两个数求和等于目标值,返回这两个数的索引组成的列表(三种方法)

给定一个整数数组nums和一个目标值target,请你在该数组中找出和为gai目标值的两个整数。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] #!...

Java高性能并发编程——线程池

在通常情况下,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以...

树莓派上传数据错误一例

首先是源码: 1 #-*- utf-8 -*- 2 #env !/usr/bin/python 3 4 importRPi.GPIO as GPIO 5 importtime 6 importjson 7 importdatetime 8 importrequests 9 10 requests.adapters.DEFAULT_RETRIES = 5...