前言
近年来,使用python的人越来越多,这得益于其清晰的语法、低廉的入门代价等因素。尽管python受到的关注日益增多,但python并非完美,例如被人诟病最多的GIL(值得注意的是,GIL并非python特性,它是在实现Python解析器(CPython)时所引入的一个概念,而CPython是大部分环境下默认的Python执行环境),全称Global Interpreter Lock。从官方定义来看,GIL无疑就是一把全局排他锁,会严重影响python多线程的效率,甚至几乎等于Python是个单线程程序。

为了满足开发者的需求,python社区推出了multiprocessing。顾名思义,multiprocessing使用了多进程而不是多线程,每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢。当然multiprocessing也并非完美,例如增加了数据通讯的难度等方面。讲了这么多背景,下面分享一下使用multiprocessing踩过的坑。由于这篇博客偏向实际工程,主要分享应用经验,相关基础知识可以查阅Python Documentation。

系统
>>> import sys
>>> print(sys.version)
3.6.0 |Anaconda 4.3.1 (64-bit)| (default, Dec 23 2016, 12:22:00) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
1
2
3
死锁
百度百科对死锁的定义

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程1。

从定义可知,永远互相等待是死锁的一个重要特征。在multiprocessing中,你稍不留神,也会犯这种错误,例如:

from multiprocessing import Process, Queue

def f(q):
q.put('X' * 1000000)

if __name__ == '__main__':
queue = Queue()
p = Process(target=f, args=(queue,))
p.start()
p.join() # this deadlocks
1
2
3
4
5
6
7
8
9
10
结果是死锁。当一个进程被join时,Python会检查被放入Queue中的数据是否已经全部删除(例如Queue.get),若没有删除,则进程会一直处于等待状态。发现这种情况时,一方面感叹“你让我找的好苦啊”,另一方面思考python的开发者怎么会对这种情况坐视不理呢?是否做了某些尝试?例如若Queue小于某个阈值,进程join会将其视为空Queue。基于这种猜想,做了以下实验

from multiprocessing import Process, Queue
import time

def f(q):
num = 10000
q.put('X' * num)
print("Finish put....")

if __name__ == '__main__':
queue = Queue()
p = Process(target=f, args=(queue,))
p.start()
print("Start to sleep...")
time.sleep(2)
print("Wake up....")
p.join()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
结果是程序正常结束,一定程度上验证了我的猜想。为了进一步确定猜想的正确性,我又做了num=1000、num=100和num=1的实验,结果均是程序正常结束,证明进程join时的确会判断Queue的大小,从而避免死锁。尽管这种策略有一定效果,但并不能根治死锁,所以进程join时一定要保证Queue中数据已经被全部取走。

除了上述的情况外,进程join自身、终止带锁的进程等情况也会导致死锁,以后会慢慢分享给大家。

结语
尽管multiprocessing对死锁有一定的容错能力,但并不完善,优化代码才是正道。
---------------------
作者:cptu
来源:CSDN
原文:https://blog.csdn.net/AckClinkz/article/details/78409301
版权声明:本文为博主原创文章,转载请附上博文链接!

python(一):multiprocessing——死锁的更多相关文章

  1. python之multiprocessing创建进程

    python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. multiprocessing创建多进程在windows和linux系统下的 ...

  2. python中multiprocessing.pool函数介绍_正在拉磨_新浪博客

    python中multiprocessing.pool函数介绍_正在拉磨_新浪博客     python中multiprocessing.pool函数介绍    (2010-06-10 03:46:5 ...

  3. python的multiprocessing模块进程创建、资源回收-Process,Pool

    python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...

  4. python多进程-----multiprocessing包

    multiprocessing并非是python的一个模块,而是python中多进程管理的一个包,在学习的时候可以与threading这个模块作类比,正如我们在上一篇转载的文章中所提,python的多 ...

  5. python多进程(multiprocessing)

    最近有个小课题,需要用到双进程,翻了些资料,还算圆满完成任务.记录一下~ 1.简单地双进程启动 同时的调用print1()和print2()两个打印函数,代码如下: #/usr/bin/python ...

  6. Python使用multiprocessing实现一个最简单的分布式作业调度系统

    Python使用multiprocessing实现一个最简单的分布式作业调度系统介绍Python的multiprocessing模块不但支持多进程,其中managers子模块还支持把多进程分布到多台机 ...

  7. python 使用multiprocessing需要注意的问题

    我们在编写程序的时候经常喜欢这样写代码 import MySQLdb import time from multiprocessing import Process conn = MySQLdb.co ...

  8. python多进程multiprocessing Pool相关问题

    python多进程想必大部分人都用到过,可以充分利用多核CPU让代码效率更高效. 我们看看multiprocessing.pool.Pool.map的官方用法 map(func, iterable[, ...

  9. Shared variable in python's multiprocessing

    Shared variable in python's multiprocessing https://www.programcreek.com/python/example/58176/multip ...

  10. python下multiprocessing和gevent的组合使用

    python下multiprocessing和gevent的组合使用 对于有些人来说Gevent和multiprocessing组合在一起使用算是个又高大上又奇葩的工作模式. Python的多线程受制 ...

随机推荐

  1. Codeforces 667D World Tour【最短路+枚举】

    垃圾csdn,累感不爱! 题目链接: http://codeforces.com/contest/667/problem/D 题意: 在有向图中找到四个点,使得这些点之间的最短距离之和最大. 分析: ...

  2. db2 获取自增主键的方法

    1.用SEQUENCES方式 建表语句 CREATE TABLE TEST1( PKEY INTEGER NOT NULL, NAME VARCHAR(100), SEX VARCHAR(100), ...

  3. 详解 CSS 七种三栏布局技巧

    作者:林东洲 链接:https://zhuanlan.zhihu.com/p/25070186 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 三栏布局,顾名思义就是 ...

  4. 前端进阶之路:初涉Less

    阅读目录 一.Less介绍 1.官方介绍 2.自己理解 3.Less.Sass.Stylus 二.Less使用入门 1.开发模式下使用Less 2.运行模式下使用Less 三.常见用法示例 1.从第一 ...

  5. Spring自带mock测试Controller

    原文:http://blog.csdn.net/yin_jw/article/details/24726941 准备SpringMVC环境 注意:使用mock测试需要引入spring-test包 Ba ...

  6. Hash分析

    分析Hash 列表内容 Hash表中的一些原理/概念,及依据这些原理/概念,自己设计一个用来存放/查找数据的Hash表,而且与JDK中的HashMap类进行比較. 我们分一下七个步骤来进行. Hash ...

  7. Android新手入门2016(7)--布局

    布局,这个在服务端变成是没有的,也是服务端的人学习client的一道坎吧. 曾经用cocos2d-x写小游戏的时候就是这个非常难懂,或者能用,可是理解不多的话,非常难写出好的布局,难以适合商业化的应用 ...

  8. 微信小程序 - 提取字体图标与其优化

    微信小程序,无论是字体图标还是图标,都差不多,只不过是为了以后字体图标修改方便,或者加效果方便而使用它而已! 1. 下载font-awesome http://fontawesome.dashgame ...

  9. HDU 1003 Max Sum (动规)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  10. async & await 的前世今生(Updated)----代码demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...