python程序中的线程操作 concurrent模块使用详解


Posted in Python onSeptember 23, 2019

一、concurrent模块的介绍

concurrent.futures模块提供了高度封装的异步调用接口

ThreadPoolExecutor:线程池,提供异步调用

ProcessPoolExecutor:进程池,提供异步调用

ProcessPoolExecutorThreadPoolExecutor:两者都实现相同的接口,该接口由抽象Executor类定义。

二、基本方法

submit(fn, *args, **kwargs) :异步提交任务

map(func, *iterables, timeout=None, chunksize=1) :取代for循环submit的操作

shutdown(wait=True) :相当于进程池的pool.close()+pool.join()操作

  • wait=True,等待池内所有任务执行完毕回收完资源后才继续
  • wait=False,立即返回,并不会等待池内的任务执行完毕
  • 但不管wait参数为何值,整个程序都会等到所有任务执行完毕
  • submit和map必须在shutdown之前

result(timeout=None) :取得结果

add_done_callback(fn) :回调函数

三、进程池和线程池

池的功能:限制进程数或线程数.

什么时候限制: 当并发的任务数量远远大于计算机所能承受的范围,即无法一次性开启过多的任务数量 我就应该考虑去限制我进程数或线程数,从保证服务器不崩.

3.1 进程池

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
def task(i):
  print(f'{current_process().name} 在执行任务{i}')
  time.sleep(1)
if __name__ == '__main__':
  pool = ProcessPoolExecutor(4) # 进程池里又4个进程
  for i in range(20): # 20个任务
    pool.submit(task,i)# 进程池里当前执行的任务i,池子里的4个进程一次一次执行任务

3.2 线程池

from concurrent.futures import ThreadPoolExecutor
from threading import Thread,currentThread
import time
def task(i):
  print(f'{currentThread().name} 在执行任务{i}')
  time.sleep(1)
if __name__ == '__main__':
  pool = ThreadPoolExecutor(4) # 进程池里又4个线程
  for i in range(20): # 20个任务
    pool.submit(task,i)# 线程池里当前执行的任务i,池子里的4个线程一次一次执行任务

四、Map的用法

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
  print('%s is runing' %os.getpid())
  time.sleep(random.randint(1,3))
  return n**2
if __name__ == '__main__':
  executor=ThreadPoolExecutor(max_workers=3)
  # for i in range(20):
  #   future=executor.submit(task,i)
  executor.map(task,range(1,21)) #map取代了for+submit

五、同步和异步

理解为提交任务的两种方式

同步: 提交了一个任务,必须等任务执行完了(拿到返回值),才能执行下一行代码

异步: 提交了一个任务,不要等执行完了,可以直接执行下一行代码.

同步:相当于执行任务的串行执行

异步

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process,current_process
import time
n = 1
def task(i):
  global n
  print(f'{current_process().name} 在执行任务{i}')
  time.sleep(1)
  n += i
  return n
if __name__ == '__main__':
  pool = ProcessPoolExecutor(4) # 进程池里又4个线程
  pool_lis = []
  for i in range(20): # 20个任务
    future = pool.submit(task,i)# 进程池里当前执行的任务i,池子里的4个线程一次一次执行任务
    # print(future.result()) # 这是在等待我执行任务得到的结果,如果一直没有结果,这里会导致我们所有任务编程了串行
                # 在这里就引出了下面的pool.shutdown()方法
    pool_lis.append(future)
  pool.shutdown(wait=True) # 关闭了池的入口,不允许在往里面添加任务了,会等带所有的任务执行完,结束阻塞
  for p in pool_lis:
    print(p.result())
  print(n)# 这里一开始肯定是拿到0的,因为我只是去告诉操作系统执行子进程的任务,代码依然会继续往下执行
  # 可以用join去解决,等待每一个进程结束后,拿到他的结果

六、回调函数

import time
from threading import Thread,currentThread
from concurrent.futures import ThreadPoolExecutor
def task(i):
  print(f'{currentThread().name} 在执行{i}')
  time.sleep(1)
  return i**2

# parse 就是一个回调函数
def parse(future):
  # 处理拿到的结果
  print(f'{currentThread().name} 结束了当前任务')
  print(future.result())
if __name__ == '__main__':
  pool = ThreadPoolExecutor(4)
  for i in range(20):
    future = pool.submit(task,i)
    '''
    给当前执行的任务绑定了一个函数,在当前任务结束的时候就会触发这个函数(称之为回调函数)
    会把future对象作为参数传给函数
    注:这个称为回调函数,当前任务处理结束了,就回来调parse这个函数
    '''
    future.add_done_callback(parse)
    # add_done_callback (parse) parse是一个回调函数
    # add_done_callback () 是对象的一个绑定方法,他的参数就是一个函数

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
布同 Python中文问题解决方法(总结了多位前人经验,初学者必看)
Mar 13 Python
python脚本实现查找webshell的方法
Jul 31 Python
python使用post提交数据到远程url的方法
Apr 29 Python
Python简单实现安全开关文件的两种方式
Sep 19 Python
Python使用matplotlib绘制三维图形示例
Aug 25 Python
python实现根据指定字符截取对应的行的内容方法
Oct 23 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
Dec 05 Python
Python : turtle色彩控制实例详解
Jan 19 Python
完美解决pyinstaller打包报错找不到依赖pypiwin32或pywin32-ctypes的错误
Apr 01 Python
python中如何使用虚拟环境
Oct 14 Python
python实现Nao机器人的单目测距
Sep 04 Python
Python Django模型详解
Oct 05 Python
Python3 pandas 操作列表实例详解
Sep 23 #Python
详解基于python-django框架的支付宝支付案例
Sep 23 #Python
如何利用Python开发一个简单的猜数字游戏
Sep 22 #Python
Python中关于浮点数的冷知识
Sep 22 #Python
Python安装及Pycharm安装使用教程图解
Sep 20 #Python
Python实现语音识别和语音合成功能
Sep 20 #Python
使用python将最新的测试报告以附件的形式发到指定邮箱
Sep 20 #Python
You might like
收音机术语解释
2021/03/01 无线电
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
2016/10/12 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
JavaScript 组件之旅(二)编码实现和算法
2009/10/28 Javascript
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
从数据库读取数据后将其输出成html标签的三种方法
2014/10/13 Javascript
javascript查询字符串参数的方法
2015/01/28 Javascript
JavaScript实现的双向跨域插件分享
2015/01/31 Javascript
node.js微信公众平台开发教程
2016/03/04 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
清除浏览器缓存的几种方法总结(必看)
2016/12/09 Javascript
js实现背景图自适应窗口大小
2017/01/10 Javascript
javascript 作用于作用域链的详解
2017/09/27 Javascript
详解如何去除vue项目中的#——History模式
2017/10/13 Javascript
详解webpack3编译兼容IE8的正确姿势
2017/12/21 Javascript
详解angular路由高亮之RouterLinkActive
2018/04/28 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
python实现flappy bird小游戏
2018/12/24 Python
python学习--使用QQ邮箱发送邮件代码实例
2019/04/16 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
Python应用实现处理excel数据过程解析
2020/06/19 Python
Numpy数组的广播机制的实现
2020/11/03 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
pycharm如何设置官方中文(如何汉化)
2020/12/29 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
荷兰男士时尚网上商店:Suitable
2017/12/25 全球购物
自我评价200字分享
2013/12/17 职场文书
什么是就业协议书
2014/04/17 职场文书
大学生实习证明范本
2014/09/19 职场文书
销售人才自我评价范文
2014/09/27 职场文书
公安民警正风肃纪剖析材料
2014/10/10 职场文书
教师节随笔
2015/08/15 职场文书
2016年大学生寒假社会实践心得体会
2015/10/09 职场文书
关于艺术节的开幕致辞
2016/03/04 职场文书
Golang中interface{}转为数组的操作
2021/04/30 Golang
vue修饰符.capture和.self的区别
2022/04/22 Vue.js