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实现正则匹配检索远端FTP目录下的文件
Mar 25 Python
Java中重定向输出流实现用文件记录程序日志
Jun 12 Python
Python中getattr函数和hasattr函数作用详解
Jun 14 Python
Python生成数字图片代码分享
Oct 31 Python
python 制作自定义包并安装到系统目录的方法
Oct 27 Python
python中property属性的介绍及其应用详解
Aug 29 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
Nov 19 Python
python实现字典嵌套列表取值
Dec 16 Python
关于python pycharm中输出的内容不全的解决办法
Jan 10 Python
解决keras,val_categorical_accuracy:,0.0000e+00问题
Jul 02 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
Oct 18 Python
python创建字典及相关管理操作
Apr 13 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作的文本留言本的例子(四)
2006/10/09 PHP
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
2011/03/23 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
PHP数组常用函数实例小结
2018/08/20 PHP
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
js身份证验证超强脚本
2008/10/26 Javascript
javascript 对象定义方法 简单易学
2009/03/22 Javascript
javascript removeChild 使用注意事项
2009/04/11 Javascript
jquery json 实例代码
2010/12/02 Javascript
ExtJS4如何给同一个formpanel不同的url
2014/05/02 Javascript
js实现简单排列组合的方法
2016/01/27 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
canvas实现粒子时钟效果
2017/02/06 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
vue.js 实现点击按钮动态添加li的方法
2018/09/07 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
2019/07/27 Javascript
vue使用echarts画组织结构图
2021/02/06 Vue.js
Python基于twisted实现简单的web服务器
2014/09/29 Python
使用Python脚本将文字转换为图片的实例分享
2015/08/29 Python
浅谈Python NLP入门教程
2017/12/25 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
Python基于pandas实现json格式转换成dataframe的方法
2018/06/22 Python
django rest framework vue 实现用户登录详解
2019/07/29 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
Python3 获取文件属性的方式(时间、大小等)
2020/03/12 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
python selenium自动化测试框架搭建的方法步骤
2020/06/14 Python
python语言中有算法吗
2020/06/16 Python
Python自动登录QQ的实现示例
2020/08/28 Python
html5拖曳操作 HTML5实现网页元素的拖放操作
2013/01/02 HTML / CSS
LightInTheBox法国站:中国跨境电商
2020/03/05 全球购物
道德之星事迹材料
2014/05/03 职场文书
考试作弊检讨书
2014/10/21 职场文书
乡镇党建工作总结2015
2015/05/19 职场文书
婚宴父亲致辞
2015/07/27 职场文书