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写的一个squid访问日志分析的小程序
Sep 17 Python
Python排序搜索基本算法之希尔排序实例分析
Dec 09 Python
python 判断网络连通的实现方法
Apr 22 Python
Python 创建空的list,以及append用法讲解
May 04 Python
JavaScript中的模拟事件和自定义事件实例分析
Jul 27 Python
Selenium的使用详解
Oct 19 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
Dec 10 Python
python使用 request 发送表单数据操作示例
Sep 25 Python
Python全栈之列表数据类型详解
Oct 01 Python
Python极值整数的边界探讨分析
Sep 15 Python
实操Python爬取觅知网素材图片示例
Nov 27 Python
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
Apr 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
全国FM电台频率大全 - 20 广西省
2020/03/11 无线电
php目录操作函数之获取目录与文件的类型
2010/12/29 PHP
php强制下载类型的实现代码
2011/04/21 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
thinkPHP删除前弹出确认框的简单实现方法
2016/05/16 PHP
用Javscript实现表单复选框的全选功能
2007/05/25 Javascript
初识javascript 文档碎片
2010/07/13 Javascript
有关JavaScript的10个怪癖和秘密分享
2011/08/28 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
学习AngularJs:Directive指令用法(完整版)
2016/04/26 Javascript
使用bootstrap3开发响应式网站
2016/05/12 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
2016/05/15 Javascript
Vue2学习笔记之请求数据交互vue-resource
2017/02/23 Javascript
js调用刷新界面的几种方式
2017/05/03 Javascript
解析vue中的$mount
2017/12/21 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
2019/06/07 Javascript
python实现绘制树枝简单示例
2014/07/24 Python
python批量生成本地ip地址的方法
2015/03/23 Python
详解Python的Django框架中Manager方法的使用
2015/07/21 Python
Python3如何解决字符编码问题详解
2017/04/23 Python
Django框架视图介绍与使用详解
2019/07/18 Python
给大家整理了19个pythonic的编程习惯(小结)
2019/09/25 Python
python中的逆序遍历实例
2019/12/25 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
python三引号如何输入
2020/07/06 Python
Python读取yaml文件的详细教程
2020/07/21 Python
canvas绘制树形结构可视图形的实现
2020/04/03 HTML / CSS
欧洲第一中国智能手机和平板电脑网上商店:CECT-SHOP
2018/01/08 全球购物
澳洲的服装老品牌:SABA
2018/02/06 全球购物
教师申诉制度
2014/01/29 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
《学会合作》教学反思
2014/04/12 职场文书
导师工作推荐信范文
2014/05/17 职场文书
英语求职信范文
2014/05/23 职场文书
如何写好活动总结
2019/06/21 职场文书
Go遍历struct,map,slice的实现
2021/06/13 Golang