话不多说,直接上代码:

import time
from functools import partial
from concurrent.futures.process import ProcessPoolExecutor # 异步回调需要加锁吗?
"""
疑问来源,在做数据分析时,为了提高程序速度,使用了进程池,并为了汇总每个进程处理的结果,使用到回调函数,
我的回调函数中需要对数据进行修改,因此不得不考虑数据安全问题。
按照我的想法:回调在进程执行完毕之后才发生,此时已经不在是并发了,那么就不会有数据安全问题,无需加锁。
但是稳妥起见,还是测试一波。
我建立了下面这个demo1,在回调的时候特地sleep2秒,然后计算程序运行总时间,根据打印结果,一共花费8秒多,
显然在处理回调函数pring_n的时候程序时同步执行的,那么自然无需加锁。
那么执行回调函数print_n的顺序是怎样的呢?是按照对应的进程结束时间调用的吗?根据源码注释:
These callables are called in the order that they were added(回调函数按照他们被添加的顺序调用)
也就是说回调函数调用顺序跟他所在进程被添加顺序一致,而非按照他所在的进程的结束时间执行。
为了验证这一点,我做了demo2,将第二个进程(i为1)sleep更长时间,从结果来看,和demo1顺序一致,
"1经过计算后的结果是1"并未在最后打印,证实了源码说法。
""" # demo1
# def count():
# for i in range(4):
# yield i
#
#
# def print_n(i, ret, obj):
# print(f'{i}经过计算后的结果是{obj.result()}')
# ret.append(obj.result())
# time.sleep(2)
#
#
# def do_calc(i):
# return i ** 2
#
#
# if __name__ == '__main__':
# s = time.time()
# l = Lock()
# pool = ProcessPoolExecutor(4)
# ret = []
# for i in range(4):
# pool.submit(do_calc, i).add_done_callback(partial(print_n, i, ret))
# pool.shutdown(wait=True)
# print('end', time.time() -s)
# print('计算结果', ret) # demo2
def count():
for i in range(4):
yield i def print_n(i, ret, obj):
print(f'{i}经过计算后的结果是{obj.result()}')
ret.append(obj.result())
if i == 1:
time.sleep(4) def do_calc(i):
return i ** 2 if __name__ == '__main__':
s = time.time()
pool = ProcessPoolExecutor(4)
ret = []
for i in range(4):
pool.submit(do_calc, i).add_done_callback(partial(print_n, i, ret))
pool.shutdown(wait=True)
print('end', time.time() -s)
print('计算结果', ret)

代码运行结果我没有打印出来,大家可以copy一下运行。

另外,python中很多并发库都支持回调机制,大家感兴趣可以试验一下,增强对并发的理解。

python异步回调顺序?是否加锁?的更多相关文章

  1. 跨平台python异步回调机制实现和使用方法

    跨平台python异步回调机制实现和使用方法 这篇文章主要介绍了python异步回调机制的实现方法,提供了使用方法代码 1 将下面代码拷贝到一个文件,命名为asyncore.py 代码如下: impo ...

  2. python异步回调函数的实现

    #coding:utf-8 from socket import * import time #简单的服务器程序 监听用户连接,接收用户发来的信息,并返回反馈 def main(): HOST = & ...

  3. Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程

    Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...

  4. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  5. (转)python异步编程--回调模型(selectors模块)

    原文:https://www.cnblogs.com/zzzlw/p/9384308.html#top 目录 0. 参考地址 1. 前言 2. 核心类 3. SelectSelector核心函数代码分 ...

  6. python异步编程--回调模型(selectors模块)

    目录 0. 参考地址 1. 前言 2. 核心类 3. SelectSelector核心函数代码分析 3.1 注册 3.2 注销 3.3 查询 4. 别名 5. 总结 6. 代码报错问题 1. 文件描述 ...

  7. State Threads——异步回调的线性实现

    State Threads——异步回调的线性实现 原文链接:http://coolshell.cn/articles/12012.html 本文的标题看起来有点拗口,其实State Threads库就 ...

  8. 深入理解 Python 异步编程(上)

    http://python.jobbole.com/88291/ 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知 ...

  9. day37 异步回调和协程

    异步回调 """ 异步任务使用场景 爬虫 1.从目标站点下载网页数据 本质就是HTML格式字符串 2.用re从字符串中提取出你需要的数据 ""&quo ...

随机推荐

  1. CET4词汇

    abandon vt.丢弃:放弃,抛弃 ability n.能力:能耐,本领 abnormal a.不正常的:变态的 aboard ad.在船(车)上:上船 abroad ad.(在)国外:到处 ab ...

  2. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.5)- 串行NOR Flash下载算法(IAR EWARM篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是IAR开发环境下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行NOR Flash XI ...

  3. 移动端 rem和flexible

    一.rem布局 rem是相对于根元素的字体大小单位. 假设html的字体大小为16px,那么1rem = 16px; 一旦根元素html定义的font-size变化,整个页面中运用到的rem都会随之变 ...

  4. VMware虚拟机安装Win7填坑

    今天本想赶紧安装Win7虚拟机做个实验,结果鼓捣了一天,写个文章填下坑. 一.Win7镜像文件下载 下载ISO镜像地址:http://msdn.itellyou.cn/ 二.安装tools VMwar ...

  5. YOLO实践初探

    学习了Andrew Ng 深度学习第三周卷积神经网络课程后,接着看了看YOLO论文,论文看得懵懵懂懂,沉不下心精雕细琢,手痒痒,迫不及待地想试一试YOLO效果.于是乎,在github上下载了ping星 ...

  6. C# 数组 ArrayList List<T>区别

    System.Collenctions和System.Collenctions.Generic 中提供了很多列表.集合和数组.例如:List<T>集合,数组Int[],String[] . ...

  7. 【基础】Linux系统的运行级别

    1.系统运行级别的配置文件 什么是运行级呢?简单的说,运行级就是操作系统当前正在运行的功能级别. 它让一些程序在一个级别启动,而另外一个级别的时候不启动. Linux系统的有效登录模式有0~9共十种, ...

  8. JavaWeb基础总结:Filter专题

    Java Servlet Filter Filter 被称为过滤器,其主要作用是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊功能 ...

  9. java instanceof 判断是否是String

    if(formbean.getBean().get("RZZGMCM") instanceof String){ formbean.getBean().put("RZZG ...

  10. 【kinetic】操作系统探索总结(五)创建简单的机器人模型smartcar

    p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify } a:link { color: r ...