博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用进程池规避Python的GIL限制
阅读量:6484 次
发布时间:2019-06-23

本文共 1786 字,大约阅读时间需要 5 分钟。

操作系统 : 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

完整代码如下:

普通单进程任务实现:

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)

完整代码如下: 

运行效果如下:

(py27env) [mike@localhost test]$ time python t1_normal.py('len : ', 2567)987real    0m17.919suser    0m17.915ssys     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 : 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)

完整代码如下:

运行效果如下:

(py27env) [mike@localhost test]$ time python t2_mp.pyqueue full('len : ', 2567)987real    0m4.917suser    0m18.356ssys     0m0.146s

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

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

本文github地址:

欢迎补充

转载地址:http://jliuo.baihongyu.com/

你可能感兴趣的文章
[LeetCode] Reverse String 翻转字符串
查看>>
学习iOS【3】数组、词典和集合
查看>>
Hessian 原理分析--转
查看>>
转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端
查看>>
easyui传入map的数据前台展示出tree格式数据
查看>>
悲观的思考,乐观的生活.我们既需要思考的深度,也需要生活的温度!
查看>>
Vitamio中文API文档(4)—— VitamioInstaller
查看>>
yii框架常用url地址
查看>>
python3.4学习笔记(十六) windows下面安装easy_install和pip教程
查看>>
MyGUI 解析
查看>>
Linux中的ls命令详细使用
查看>>
graph-tool文档(一)- 快速开始使用Graph-tool - 2.属性映射、图的IO和Price网络
查看>>
GraphicsLab Project之辉光(Glare,Glow)效果 【转】
查看>>
Linux Curl命令
查看>>
-27979 LoadRunner 错误27979 找不到请求表单 Action.c(73): Error -27979: Requested form not found...
查看>>
[LeetCode] Minimum Depth of Binary Tree
查看>>
,net运行框架
查看>>
Java 中 Emoji 的正则表达式
查看>>
Mixin Network第一届开发者大赛作品介绍- dodice, diceos和Fox.one luckycoin
查看>>
安卓Glide(4.7.1)使用笔记 01 - 引入项目
查看>>