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 24 Python
Python中的异常处理简明介绍
Apr 13 Python
让python 3支持mysqldb的解决方法
Feb 14 Python
python图书管理系统
Apr 05 Python
python如何使用unittest测试接口
Apr 04 Python
python实现停车管理系统
Nov 30 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
Dec 02 Python
pytorch实现MNIST手写体识别
Feb 14 Python
python实现word文档批量转成自定义格式的excel文档的思路及实例代码
Feb 21 Python
Python pip安装模块提示错误解决方案
May 22 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
Oct 15 Python
python标准库ElementTree处理xml
May 20 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中的Class的几点个人看法
2006/10/09 PHP
PHP4中session登录页面的应用
2008/07/25 PHP
调试PHP程序的多种方法介绍
2014/11/06 PHP
PHP实现恶意DDOS攻击避免带宽占用问题方法
2015/05/27 PHP
基于ThinkPHP实现批量删除
2015/12/18 PHP
Yii2实现log输出到file及database的方法
2016/11/12 PHP
ArrayList类(增强版)
2007/04/04 Javascript
jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
2010/04/18 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
2014/04/23 Javascript
jquery队列函数用法实例
2014/12/16 Javascript
js实现网站最上边可关闭的浮动广告条代码
2015/09/04 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
2016/05/21 Javascript
Javascript中常用的检测方法小结
2016/10/08 Javascript
NodeJS学习笔记之Module的简介
2017/03/24 NodeJs
微信小程序webview 脚手架使用详解
2019/07/22 Javascript
[01:41]DOTA2超级联赛专访YYF 称一辈子难忘TI2
2013/05/28 DOTA
[01:06:32]DOTA2上海特级锦标赛D组资格赛#1 EG VS VP第一局
2016/02/28 DOTA
[49:27]LGD vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python中的自省(反射)详解
2015/06/02 Python
详解 Python 读写XML文件的实例
2017/08/02 Python
python中时间转换datetime和pd.to_datetime详析
2019/08/11 Python
Python qrcode 生成一个二维码的实例详解
2020/02/12 Python
python mysql 字段与关键字冲突的解决方式
2020/03/02 Python
Django自关联实现多级联动查询实例
2020/05/19 Python
django创建css文件夹的具体方法
2020/07/31 Python
浅析两列自适应布局的3种思路
2016/05/03 HTML / CSS
仓库主管的岗位职责
2013/12/04 职场文书
大班上学期幼儿评语
2014/04/30 职场文书
做人民满意的公务员活动方案
2014/08/25 职场文书
党性分析材料格式
2014/12/19 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
如何用Navicat操作MySQL
2021/05/12 MySQL
Python中如何处理常见报错
2022/01/18 Python