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实现合并字典的方法
Jul 07 Python
python计算一个序列的平均值的方法
Jul 11 Python
编写Python小程序来统计测试脚本的关键字
Mar 12 Python
matplotlib在python上绘制3D散点图实例详解
Dec 09 Python
详解python读取和输出到txt
Mar 29 Python
使用pyqt 实现重复打开多个相同界面
Dec 13 Python
Django 博客实现简单的全文搜索的示例代码
Feb 17 Python
Python关键字及可变参数*args,**kw原理解析
Apr 04 Python
Python定时任务APScheduler安装及使用解析
Aug 07 Python
基于Python爬取搜狐证券股票过程解析
Nov 18 Python
Python 调用 ES、Solr、Phoenix的示例代码
Nov 23 Python
Python卷积神经网络图片分类框架详解分析
Nov 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
php输入流php://input使用浅析
2014/09/02 PHP
ThinkPHP表单自动验证实例
2014/10/13 PHP
PHP入门教程之面向对象基本概念实例分析
2016/09/11 PHP
给大家分享几个常用的PHP函数
2017/01/15 PHP
yii2 commands模式以及配置crontab定时任务的方法
2017/08/19 PHP
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
利用a标签自动解析URL分析网址实例
2014/10/20 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
js进行表单验证实例分析
2015/02/10 Javascript
AngularJS实现的回到顶部指令功能实例
2017/05/17 Javascript
JSON 数据格式详解
2017/09/13 Javascript
jQuery实现简单日期格式化功能示例
2017/09/19 jQuery
详解React 在服务端渲染的实现
2017/11/16 Javascript
原生JS实现前端本地文件上传
2018/09/08 Javascript
微信小程序自定义多列选择器使用详解
2019/06/21 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
python实现推箱子游戏
2020/03/25 Python
详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
2019/08/23 Python
html5+css3之动画在webapp中的应用
2014/11/21 HTML / CSS
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
史泰博(Staples)中国官方网站:办公用品一站式采购
2016/09/05 全球购物
广告设计专业自荐信范文
2013/11/14 职场文书
护士辞职信范文
2014/01/19 职场文书
经营管理策划方案
2014/05/22 职场文书
电子商务专业应届生求职信
2014/05/28 职场文书
旅游文化节策划方案
2014/06/06 职场文书
2014年政风行风工作总结
2014/11/22 职场文书
全陪导游词开场白
2015/05/29 职场文书
幼儿园小班教师随笔
2015/08/14 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书
python实现简单区块链结构
2021/04/25 Python
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技
德劲DE1102数字调谐收音机机评
2022/04/07 无线电