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 Deque 模块使用详解
Jul 04 Python
Python实现基于HTTP文件传输实例
Nov 08 Python
python、java等哪一门编程语言适合人工智能?
Nov 13 Python
Python实现mysql数据库更新表数据接口的功能
Nov 19 Python
PyCharm 常用快捷键和设置方法
Dec 20 Python
django DRF图片路径问题的解决方法
Sep 10 Python
详解python使用turtle库来画一朵花
Mar 21 Python
python绘制封闭多边形教程
Feb 18 Python
iPython pylab模式启动方式
Apr 24 Python
keras多显卡训练方式
Jun 10 Python
用python爬虫批量下载pdf的实现
Dec 01 Python
Python-OpenCV实现图像缺陷检测的实例
Jun 11 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
在php MYSQL中插入当前时间
2008/04/06 PHP
PHP实用函数分享之去除多余的0
2015/02/06 PHP
jQuery.getScript加载同域JS的代码
2012/02/13 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
2014/02/07 Javascript
JS 弹出层 定位至屏幕居中示例
2014/05/21 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
jQuery语法小结(超实用)
2015/12/31 Javascript
实例讲解javascript注册事件处理函数
2016/01/09 Javascript
JavaScript学习笔记之数组求和方法
2016/03/23 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
layui获取多选框中的值方法
2018/08/15 Javascript
JS函数内部属性之arguments和this实例解析
2018/10/07 Javascript
jQuery创建折叠式菜单
2019/06/15 jQuery
ElementUI多个子组件表单的校验管理实现
2019/11/07 Javascript
es6中class类静态方法,静态属性,实例属性,实例方法的理解与应用分析
2020/02/15 Javascript
Python中set与frozenset方法和区别详解
2016/05/23 Python
分享python数据统计的一些小技巧
2016/07/21 Python
python实现定时提取实时日志程序
2018/06/22 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
如何用Python制作微信好友个性签名词云图
2019/06/28 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
2019/09/25 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
德国香水、化妆品和护理产品网上商店:Parfumdreams
2018/09/26 全球购物
佳能法国商店:Canon法国
2019/02/14 全球购物
新三好学生主要事迹
2014/01/23 职场文书
小学新学期寄语
2014/04/02 职场文书
少先队辅导员事迹材料
2014/12/24 职场文书
安全责任协议书范本
2016/03/23 职场文书
Python基础之教你怎么在M1系统上使用pandas
2021/05/08 Python