前言
近年来,使用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. HDU 5667 Sequence【矩阵快速幂+费马小定理】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5667 题意: Lcomyn 是个很厉害的选手,除了喜欢写17kb+的代码题,偶尔还会写数学题.他找到 ...

  2. php 笔记 汇总 学习

    php命令行:通过命令行进入到当前要被执行的php文件路径,然后输入php环境可执行路径(后面包含php.exe),然后输入要被执行的php文件,比如runData.php即可. php框架:yaf. ...

  3. 【TFS】TFS2015链接TFS出现TF31002/TF400324问题解决方案

    安装VS2015后链接TFS发现出现TF31002错误,然后用浏览器打开TFS URL能正常访问,在TFS online中点击用vs打开按钮,提示TF400324错误 1. VS2015中打开: 2. ...

  4. 如何稳定地使用 Google 搜索https://encrypted.google.com/

    方法很简单.用记事本打开 hosts 文件(Windows Vista 和 Windows 7 用户请先使用管理员权限打开记事本,然后将 hosts 文件拖进记事本中),在最下面添加如下内容: 203 ...

  5. Python爬虫之简单的图片获取

    简单的静态网页的图片获取: import urllib import re import os url = 'http://www.toutiao.com/a6467889113046450702/' ...

  6. win7系统使用engine进行开发报错,“未能加载文件或程序集”

    http://www.gisall.com/wordpress/?p=7161 使用vs2010加 arcengine 开发winfrom应用,新建了uc,拖了几个控件后,编译,报未能加载文件或程序集 ...

  7. 基于Office 365 无代码工作流分析-表单基本需求分析!

     3.2表单的制作 基于下图的需求,我们须要定义例如以下的表单列表:

  8. SolidEdge如何在零件上写字 如何绘制文字

    在草图状态下,插入-文字轮廓   可以按这两个按钮调节文字的大小和位置   之后你可以通过长出或除料把文字凸起或者凹下去   如果你要制作路径文字(比如环形文字),则先绘制一条圆或一段圆弧,并设为构造 ...

  9. 有关不同浏览器不同版本号的css以及js计算高度的问题

    1.input在全部浏览器以及全部的版本号中,都是定义了高度.然后再定义padding或者border值.这时候都会撑开.高度是本身的高度在padding值和border值 2.select在gool ...

  10. HTML初体验

    ios讨论群1群:135718460 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,它规定了自己的语法规则,用来表示比"文本"更丰富 ...