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中使用 Selenium 实现网页截图实例
Jul 18 Python
tensorflow构建BP神经网络的方法
Mar 12 Python
dataframe设置两个条件取值的实例
Apr 12 Python
Python使用sort和class实现的多级排序功能示例
Aug 15 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
Oct 17 Python
python numpy 按行归一化的实例
Jan 21 Python
Python matplotlib以日期为x轴作图代码实例
Nov 22 Python
Keras实现将两个模型连接到一起
May 23 Python
详解python实现可视化的MD5、sha256哈希加密小工具
Sep 14 Python
利用python查看数组中的所有元素是否相同
Jan 08 Python
matplotlib交互式数据光标mpldatacursor的实现
Feb 03 Python
python实现简单的聊天小程序
Jul 07 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
在PWS上安装PHP4.0正式版
2006/10/09 PHP
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
详细解读PHP中接口的应用
2015/08/12 PHP
php表单提交实例讲解
2015/11/12 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
PHP 二维数组和三维数组的过滤
2016/03/16 PHP
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
jQuery.form插件的使用及跨域异步上传文件
2016/04/27 Javascript
jquery判断checkbox是否选中及改变checkbox状态的实现方法
2016/05/26 Javascript
微信小程序 navigation API实例详解
2016/10/02 Javascript
ionic2 tabs使用 Modal底部tab弹出框
2016/12/30 Javascript
angularjs中使用ng-bind-html和ng-include的实例
2017/04/28 Javascript
详解node字体压缩插件font-spider的用法
2018/09/28 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
2019/09/17 Javascript
[01:31](回顾)杀出重围,决战TI之巅
2014/07/01 DOTA
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
Python黑魔法@property装饰器的使用技巧解析
2016/06/16 Python
[原创]python爬虫(入门教程、视频教程)
2018/01/08 Python
浅谈Python采集网页时正则表达式匹配换行符的问题
2018/12/20 Python
对Python3使运行暂停的方法详解
2019/02/18 Python
python实现根据文件格式分类
2019/10/31 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
HTML5 Canvas 绘图——使用 Canvas 绘制图形图文教程 使用html5 canvas 绘制精美的图
2015/08/31 HTML / CSS
伦敦高级内衣品牌:Agent Provocateur(大内密探)
2016/08/23 全球购物
AVIS安飞士奥地利租车官网:提供奥地利、欧洲和全世界汽车租赁
2016/11/29 全球购物
数据库测试通常都包括哪些方面
2015/11/30 面试题
村级个人对照检查材料
2014/08/22 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
义卖募捐活动总结
2015/05/09 职场文书
Python访问Redis的详细操作
2021/06/26 Python
python机器学习实现oneR算法(以鸢尾data为例)
2022/03/03 Python
GoFrame基于性能测试得知grpool使用场景
2022/06/21 Golang