说说GIL

上一篇:线程深入篇引入

Code:https://github.com/lotapp/BaseCode/tree/master/python/5.concurrent/Thread/3.GIL

说说GIL

尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的,所以这时候才引入了GIL

解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行(保证C实现部分能线程安全) GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)

注意:GIL只会影响到那些严重依赖CPU的程序(比如计算型的)如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适 ~ 因为它们大部分时间都在等待(线程被限制到同一时刻只允许一个线程执行这样一个执行模型。GIL会根据执行的字节码行数和时间片来释放GIL,在遇到IO操作的时候会主动释放权限给其他线程)

所以Python的线程更适用于处理I/O和其他需要并发执行的阻塞操作,而不是需要多处理器并行的计算密集型任务(对于IO操作来说,多进程和多线程性能差别不大)计算密集现在可以用Python的Ray框架

网上摘取一段关于IO密集和计算密集的说明:(IO密集型可以结合异步)

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

Process and Thread Test

其实用不用多进程看你需求,不要麻木使用,Linux下还好点,Win下进程开销就有点大了(好在服务器基本上都是Linux,程序员开发环境也大多Linux了)这边只是简单测了个启动时间差距就来了,其他的都不用测试了

测试Code:

from time import sleep
from multiprocessing import Processdef test(i):sleep(1)print(i)def main():t_list = [Process(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

运行时间:

real    0m3.980s
user    0m2.034s
sys  0m3.119s

操作系统几千个进程开销还是有点大的(毕竟进程是有上线的)ulimit -a
9.MaxProcess.png

测试Code:

from time import sleep
from multiprocessing.dummy import Processdef test(i):sleep(1)print(i)def main():t_list = [Process(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

运行时间:

real    0m1.130s
user    0m0.158s
sys  0m0.095s

multiprocessing.dummy里面的Process上面也说过了,就是在线程基础上加点东西使得用起来和multiprocessingProcess编程风格基本一致(本质还是线程)

测试Code:

from time import sleep
from multiprocessing.dummy import threadingdef test(i):sleep(1)print(i)def main():t_list = [threading.Thread(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

运行时间:

real    0m1.123s
user    0m0.154s
sys  0m0.085s

其实Redis就是使用单线程和多进程的经典,它的性能有目共睹。所谓性能无非看个人能否充分发挥罢了。不然就算给你轰炸机你也不会开啊?扎心不老铁~

PS:线程和进程各有其好处,无需一棍打死,具体啥好处可以回顾之前写的进程和线程篇~


利用共享库来扩展

C系扩展

GIL是Python解释器设计的历史遗留问题,多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。计算密集型任务要真正利用多核,除非重写一个不带GIL的解释器(PyPy)如果一定要通过多线程利用多核,可以通过C扩展来实现(Python很多模块都是用C系列写的,所以用C扩展也就不那么奇怪了

只要用C系列写个简单功能(不需要深入研究高并发),然后使用ctypes导入使用就行了:

#include <stdio.h>  void test()  
{  while(1){}
}

编译成共享库:gcc 2.test.c -shared -o libtest.so
9.共享库.png

使用Python运行指定方法:(太方便了,之前一直以为C#调用C系列最方便,用完Python才知道更简方案

from ctypes import cdll
from os import cpu_count
from multiprocessing.dummy import Pooldef main():# 加载C共享库(动态链接库)lib = cdll.LoadLibrary("./libtest.so")pool = Pool()  # 默认是系统核数pool.map_async(lib.test, range(cpu_count()))pool.close()pool.join()if __name__ == '__main__':main()

看看这时候HTOP的信息:(充分利用多核)【ctypes在调用C时会自动释放GIL
9.ctypes.png

Go扩展

利用Go写个死循环,然后编译成so动态链接库(共享库):

package main
import "C"//export test
func test(){for true{}
}func main() {test()
}

非常重要的事情://export test一定要写,不然就被自动改成其他名字(我当时被坑过)

Python调用和上面一样:

from ctypes import cdll
from os import cpu_count
from multiprocessing.dummy import Pooldef main():# 加载动态链接库lib = cdll.LoadLibrary("./libtestgo.so")pool = Pool()  # 默认是系统核数pool.map_async(lib.test, range(cpu_count()))pool.close()pool.join()if __name__ == '__main__':main()

效果:go build -buildmode=c-shared -o libtestgo.so 2.test.go
9.golang.png


题外话~如果想等CPython的GIL消失可以先看一个例子:MySQL把大锁改成各个小锁花了5年。在是在MySQL有专门的团队和公司前提下,而Python完全靠社区重构就太慢了

速度方面微软除外,更新快本来是好事,但是动不动断层更新,这学习成本就太大了(这也是为什么Net能深入的人比较少的原因:人家刚深入一个,你就淘汰一个了...)

可能还有人不清楚,贴下官方推荐技术吧(NetCoreOrleansEFCoreML.NetCoreRT

https://github.com/aspnet/AspNetCorehttps://github.com/aspnet/EntityFrameworkCorehttps://github.com/dotnet/machinelearninghttps://github.com/dotnet/orleanshttps://github.com/aspnet/Mvchttps://github.com/dotnet/corert

课外拓展:

用go语言给python3开发模块
https://www.jianshu.com/p/40e069954804
https://blog.filippo.io/building-python-modules-with-go-1-5Python与C/C++相互调用
https://www.cnblogs.com/apexchu/p/5015961.html使用C/C++代码编写Python模块
https://www.cnblogs.com/silvermagic/p/9087896.html快速实现python c扩展模块
https://www.cnblogs.com/chengxuyuancc/p/6374239.htmlPython的C语言扩展
https://python3-cookbook.readthedocs.io/zh_CN/latest/chapters/p15_c_extensions.htmlpython调用golang生成的so库
https://studygolang.com/articles/10228
https://www.cnblogs.com/huangguifeng/p/8931837.htmlpython调用golang并回调
https://blog.csdn.net/gtd138/article/details/79801235Python3.x AttributeError: libtest.so: undefined symbol: fact
https://www.cnblogs.com/tanglizi/p/8965230.html

运行在其他编译器上

先看最重要的一点,一旦运行在其他编译器意味着很多Python第三方库可能就不能用了,相对来说PyPy兼容性是最好的了

如果是Python2系列我推荐谷歌的grumpy

Grumpy是一个 Python to Go 源代码转换编译器和运行时。旨在成为CPython2.7的近乎替代品。关键的区别在于它将Python源代码编译为Go源代码,然后将其编译为本机代码,而不是字节码。这意味着Grumpy没有VM已编译的Go源代码是对Grumpy运行时的一系列调用,Go库提供与 Python C API类似的目的

如果是Python3系列,可以使用PyPy PythonNet Jython3 ironpython3等等

PyPy:https://bitbucket.org/pypy/pypy

Net方向:

https://github.com/pythonnet/pythonnet
https://github.com/IronLanguages/ironpython3

Java方向:

https://github.com/jython/jython3

Other:

源码:https://github.com/sbinet/go-python
参考:https://studygolang.com/articles/13019可惜CoreRT一直没完善,不然就Happy了
https://github.com/dotnet/corert

经验平时基本上多线程就够用了,如果想多核利用-多进程基本上就搞定了(分布式走起)实在不行一般都是分析一下性能瓶颈在哪,然后写个扩展库

如果需要和其他平台交互才考虑上面说的这些项目。如果是Web项目就更不用担心了,现在哪个公司还不是混用?JavaScript and Python and Go or Java or NetCore。基本上上点规模的公司都会用到Python,之前都是Python and Java搭配使用,这几年开始慢慢变成Python and Go or NetCore搭配使用了~

下集预估:Actor模型 and 消息发布/订阅模型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021重庆高考成绩名次排名查询,重庆高考排名对应大学-重庆高考位次大学(2021年理科)...

选择科目测一测我能上哪些大学选择科目领取你的专属报告>选择省份关闭请选择科目确定v>每年高考结束后&#xff0c;报大学、选专业、填志愿就成了考生与家长十分关心的一件事情。本期&#xff0c;圆梦志愿为大家整理了重庆高考理科2020年位次排名对应的大学&#xff0c;供…

Project项目信息的日程排定方法区别

日程排定方法分&#xff1a;项目开始日期&#xff0c;项目结束日期。 项目开始日期 设置如下 在“工期”单元格输入任意数字&#xff0c;任务开始日期会从项目开始日期2020年3月1日开始 给项目任务设置工期的时候&#xff0c;从任务的第一个开始设置&#xff0c;按正序进行&a…

gis里创建要素面板怎么打开_周末技术流 | GIS三维热力图分析

周末技术流&#xff2e;&#xff2f;&#xff37;现在行动&#xff01;我们的技术流是一个系列&#xff0c;最终带大家出一套完整图纸哦~(未经允许严禁盗用&#x1f6ab;)Rhino日照分析1.前期回顾本期内容一直关注我们的朋友到这期可能会有点熟悉&#xff0c;确实&#xff0c;我…

project提醒:无法链接这些任务,因为它们已通过另一个任务链链接

给45任务指定前置任务111时&#xff0c;提示“无法链接这些任务&#xff0c;因为它们已通过另一个任务链链接” 查了好久没找到原因&#xff0c;后来无意在46任务前置任务输入111&#xff0c;没有提示。 解决方法&#xff1a; 删除了提示的45任务&#xff0c;新建任务&#x…

企业网站 源码 e-mail_天津seo优化套餐服务收费_天津网站优化关键词价格

天津华阳在线专注于SEO关键词排名优化&#xff0c;品牌网站建设&#xff0c;营销型网站建设&#xff0c;App、小程序开发&#xff0c;搜索引擎seo优化&#xff0c;竞价托管sem&#xff0c;品牌口碑建设与代运营等服务。企业通过引进前BAT产品经理不断丰富产品线优化技术实力&am…

必须Mark下,2019 年度中国质量协会质量技术优秀奖

曾经和一群可爱的人儿做的项目&#xff0c;获得了2019 年度中国质量协会质量技术优秀奖&#xff0c;无心插柳柳成荫。 那几年工作得很快乐&#xff0c;工作与家庭都兼顾&#xff0c;是同事也是朋友。2019年末去过一次移动宁波分公司&#xff0c;特意去看了原来驻场的办公室&am…

python文件编码及执行

兼容中文编码 由于Python源代码也是一个文本文件&#xff0c;所以&#xff0c;当你的源代码中包含中文的时候&#xff0c;在保存源代码时&#xff0c;就需要务必指定保存为UTF-8编码。 当Python解释器读取源代码时&#xff0c;为了让它按UTF-8编码读取&#xff0c;我们通常在文…

这些Windows 10隐藏秘技,你知道几个?

1. 虚拟桌面 玩电脑的老鸟&#xff0c;估计都听说过虚拟桌面。简言之&#xff0c;平时要做的工作太多&#xff0c;又没有第二个显示器&#xff0c;那么“虚拟桌面”也就成了不二之选。微软Windows 10的虚拟桌面隐藏在WinTAB中&#xff0c;也就是所谓的时间线视图&#xff08;T…

vant toast loading 倒计时_日期倒计时软件哪个好 苹果日期倒计时软件推荐

日期倒计时软件哪个好&#xff0c;相信大家也是经常会查看日期&#xff0c;来保证一些重要的事情能够按时进行&#xff0c;那么哪一款日期倒计时软件比较好用&#xff0c;能够提醒用户们日期将至呢。这里就为大家推荐几款。日期倒计时软件哪个好1.Days Matter Air作为Days Matt…

业务应用系统的业务操作日志设计

目的&#xff1a;记录业务的访问活动 操作时间&#xff1a;精确到秒 服务器IP&#xff1a;可能部署多台服务器&#xff0c;记录当前线程服务器IP地址 访问者IP&#xff1a;访问者ip地址 访问者账号&#xff1a;系统通过手机号登录&#xff0c;记录手机号 业务名称&#xf…

c char转int_c/c++基础之sizeof用法

在 C/C 中&#xff0c;sizeof() 是一个判断数据类型或者表达式长度的运算符。1 sizeof 定义 sizeof 是 C/C 中的一个操作符&#xff08;operator&#xff09;&#xff0c;返回一个对象或者类型所占的内存字节数。The sizeof keyword gives the amount of storage, in bytes, as…

非结构化数据与结构化数据提取---- BeautifulSoup4 解析器

CSS 选择器&#xff1a;BeautifulSoup4 和 lxml 一样&#xff0c;Beautiful Soup 也是一个HTML/XML的解析器&#xff0c;主要的功能也是如何解析和提取 HTML/XML 数据。 lxml 只会局部遍历&#xff0c;而Beautiful Soup 是基于HTML DOM的&#xff0c;会载入整个文档&#xff0c…

pyaudio usb playback_5.5寸触控屏IP电话会议USB全向麦克风NK-OAM600U_影视工业网

寸触控屏视频会议USB全向麦克风(拾音器)NK-OAM600U概述&#xff1a;派尼珂NK-OAM600U视频会议USB全向麦克风&#xff0c;是一款配置多点手势触控FHD屏的高清会议电话&#xff0c;便捷的连接方式&#xff1a;支持USB/以太网/WIFI/蓝牙Bluetooth连接&#xff0c;同时支持外接视频…

微软发布Azure Storage不可变存储功能的正式版本

随着新的不可变存储功能的发布&#xff0c;blob特性在特定的保留期间内将是不可以擦除和修改的。该特性从今年6月份开始进行预览使用&#xff0c;现在&#xff0c;微软宣布它在所有公开Azure region中正式发布。\\微软添加对不可变存储的支持&#xff0c;以便于帮助客户遵循像S…

红米note5手机插u盘没反应_认真分析下:荣耀智慧屏x1和红米x50对比哪个好?用后一个月告诉大家实情...

这二款电视荣耀智慧屏x1和红米x50区别还是有的哈&#xff0c;外观和款式是不一样的&#xff0c;不过家用都是可以的&#xff0c;看个人吧&#xff0c;我自己用的是荣耀智慧屏x1&#xff0c;款式是我喜欢的&#xff0c;多时尚的&#xff0c;整体质感不错的&#xff0c;看上去很大…

用Excel函数提高效率

今天在计划20某年项目采购各阶段时间点&#xff0c;从合同计划签订日期开始倒退。 规则如下&#xff1a; 项目采购申请----&#xff08;1-2个工作日&#xff09;---->项目立项----&#xff08;1-2个工作日&#xff09;--->采购小组成立-----&#xff08;2-3个工作日&am…

python测试工具开发面试宝典3web抓取

2019独角兽企业重金招聘Python工程师标准>>> 用requests输出网站返回头 输出 https://china-testing.github.io/ 的返回头 参考答案In [1]: import requestsIn [2]: url https://china-testing.github.io/In [3]: response requests.get(url)In [4]: response.req…

计算机网络本直通线的制作方法,电脑网络:教你一分钟自制高质量网线(含水晶头分类),不求人...

在文章开头&#xff0c;我们首先来介绍一下制作水晶头需要用到的工具——网线钳。这不是多么高科技的东西&#xff0c;价格也不贵&#xff0c;普通用户都能接受&#xff0c;从网上或是线下都能买到。网线水晶头的制作及检测方法&#xff0c;从来没人写过这么全我们主要用到网线…

sap crm button_正值SAP中国成立25周年之际,江苏金来奇智能科技SAPB1项目正式启动...

正值SAP中国成立25周年之际&#xff0c;江苏金来奇智能科技的SAP项目于2020年11月02日正式启动&#xff0c;代表着SAPB1在智能装备行业又一成功的案例。江苏金来奇隶属于无锡金鑫集团股份有限公司&#xff0c;无锡金鑫集团股份有限公司坐落于风景秀丽的太湖之滨&#xff0c;位于…

it项目管理 pdf_IT项目管理的控制经验

据调查&#xff0c;只有37%的IT项目在计划时间内完成&#xff0c;42%的在预算内完成。IT项目成功率不高的根源在于IT项目管理是项系统工程&#xff0c;不仅需要项目经理个人具备一定的组织、决策、技术、业务、沟通能力&#xff0c;更需要运用多种手段对项目的时间、质量、成本…