操作系统 : CentOS7.3.1611_x64

python版本:2.7.5

问题描述

Python的GIL会对CPU密集型的程序产生影响,如果完全使用Python来编程,怎么避开GIL的限制呢?

解决方案

在多线程中使用进程池来规避GIL的限制。具体如下:

1、使用multiprocessing模块来创建进程池;

2、将计算任务分配给不同的线程;

3、在任务线程中把任务提交给之前创建的进程池;

每当有线程要执行cpu密集型任务时,就把该任务提交到进程池中,然后进程池会将任务交给运行在另一个进程中的Python解释器。

当线程等待结果时会释放GIL,而此时的计算任务是在另一个单独的Python解释器中执行的,不再受到GIL的限制了。

在多核系统中采用这个方案能轻易地利用到所有的CPU核心。

假设有这样的worker函数:

def worker(arr):
s = 0
for n in arr :
arrTmp = range(1,n+1)
if len(arrTmp) == 0 : continue
rtmp = 1
for i in arrTmp :
rtmp *= i
s += rtmp
return s

完整代码如下:https://github.com/mike-zhang/pyExamples/blob/master/gilAvoid/gilAvoidTest1/taskCommon.py

普通单进程任务实现:

def main():
s = 0
tStart,tStop = 1,1000
for i in range(1,100):
#t = worker(range(tStart,tStop))
t = worker(range(1,1000))
s += t
tStart = tStop
tStop += 1000
print("len : ",len(str(s)))
print(s%10000)

完整代码如下: https://github.com/mike-zhang/pyExamples/blob/master/gilAvoid/gilAvoidTest1/t1_normal.py

运行效果如下:

(py27env) [mike@localhost test]$ time python t1_normal.py
('len : ', ) real 0m17.919s
user 0m17.915s
sys 0m0.003s

使用进程池的实现:

def wokerThread(start,stop):
#r = gPool.apply(worker,(range(start,stop),))
r = gPool.apply(worker,(range(1,1000),))
q.put(r)
# E-Mail : Mike_Zhang@live.com
def main():
s = 0
thrdArr = []
tStart,tStop = 1,1000
for i in range(1,gCount+1):
thrd = threading.Thread(target=wokerThread,args=(tStart,tStop))
thrdArr.append(thrd)
tStart = tStop
tStop += 1000
for t in thrdArr :
t.daemon = True
t.start()
while not q.full(): time.sleep(0.1)
while not q.empty(): s += q.get()
print("len : ",len(str(s)))
print(s%10000)

完整代码如下:https://github.com/mike-zhang/pyExamples/blob/master/gilAvoid/gilAvoidTest1/t2_mp.py

运行效果如下:

(py27env) [mike@localhost test]$ time python t2_mp.py
queue full
('len : ', ) real 0m4.917s
user 0m18.356s
sys 0m0.146s

可以看出使用上述方法可以规避GIL的限制(测试机器为i5 4核),程序的速度得到明显的提升。

好,就这些了,希望对你有帮助。

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2017/20170819_使用进程池规避python的GIL限制.rst

欢迎补充

使用进程池规避Python的GIL限制的更多相关文章

  1. GIL 线程池 进程池 同步 异步

    1.GIL(理论 重点)2.线程池 进程池3.同步 异步 GIL 是一个全局解释器锁,是一个互斥锁 为了防止竞争解释器资源而产生的 为何需要gil:因为一个python.exe进程中只有一份解释器,如 ...

  2. python GIL锁、进程池与线程池、同步异步

    一.GIL全局解释器锁 全局解释器锁 在CPython中,全局解释器锁(GIL)是一个互斥锁,它可以防止多个本机线程同时执行Python代码.之所以需要这个锁,主要是因为CPython的内存管理不是线 ...

  3. python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程

    GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...

  4. Python学习之GIL&进程池/线程池

    8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...

  5. Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池

    Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...

  6. GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论

    昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...

  7. 4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞

    一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点:  保 ...

  8. python进程池剖析(一)

    python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...

  9. Python 多进程和进程池

    一,前言 进程:是程序,资源集合,进程控制块组成,是最小的资源单位 特点:就对Python而言,可以实现真正的并行效果 缺点:进程切换很容易消耗cpu资源,进程之间的通信相对线程来说比较麻烦 线程:是 ...

随机推荐

  1. (转载)Java自带的GUI性能监控工具Jconsole以及JisualVM简介

    原文链接:http://blog.csdn.net/chendc201/article/details/22905503 1 Jconsole 1.1 简介以及连接 JConsole是一个基于JMX的 ...

  2. AT&T汇编helloworld

    摘自:http://blog.163.com/guixl_001/blog/static/417641042012112102642703/ 代码: #hello.s .data # 数据段声明 ms ...

  3. QC使用:

    qc使用入门 qc使用安装篇:附链接http://www.cnblogs.com/alterhu/archive/2011/11/05/2237483.html qc使用配置篇:附链接http://w ...

  4. CentOS 6.9上安装mysql-5.6.36

    CentOS 6.9上安装mysql-5.6.36 1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/data,而后需要创建/da ...

  5. Oracle PIVOT 行转列方法

    数据库中業種的存储如下图: SELECT * FROM M_TORIHIKISAKI_GYOSYU 其中GYIUSYU_CD字段代表不同的業種 而画面需要实现下图所示样式:(将每条数据的業種横向展开显 ...

  6. hdu_1711: Number Sequence【KMP算法】

    题目链接 此次插播点笔记 hdu中点击蓝色的"Compilation Error"可以查看自己是为什么CE的 hdu中提交的话,语言选择G++可以使用<bits/stdc++ ...

  7. Python基础之常用模块(三)

    1.configparser模块 该模块是用来对文件进行读写操作,适用于格式与Windows ini 文件类似的文件,可以包含一个或多个节(section),每个节可以有多个参数(键值对) 配置文件的 ...

  8. OI内的排列与组合(简单版)

    §1基本原理 △让我们来看下面问题: 从甲地到乙地,可以乘火车,也可以乘汽车,还可以乘轮船.一天中,火车有4班,汽车有2班,轮船有3班.那么,一天中乘坐这些交通工具从甲地到乙地共有多少种不同走法?△分 ...

  9. BI服务器配置与客户端情况

    1. BI描述 FineBI是一款纯B/S端的商业智能分析服务平台:支持通过web应用服务器将其部署在服务器上,提供企业云服务器.用户端只需要使用一个浏览器即可进行服务平台的访问和使用.因此在配置使用 ...

  10. Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory

    前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext 约束: 本文指定contextClass为默认的XmlWebApplicati ...