小编写这篇文章的一个主要目的,主要是来给大家去做一个详细解答,解答的内容是对python多线程的一个相关理解,包括其对多核cpu利用的一个详细解析,具体的内容,请各位读者仔细的进行阅读下文。
引言
我们经常听到"因为GIL的存在,python的多线程不能利用多核CPU",现在我们暂且不提GIL,python能不能利用多核cpu,今天我做了一个实验,代码很简单如下所示
while 1: pass
没有运行这段代码前cpu状态
运行之后的状态
下面两张图是运行之后的状态,当然这只是两张比较有代表性的图,截图间隔有十几秒的样子
根据第一张图我们发现cpu1、cpu3的负载有明显增长,我们可以得出python线程是可以利用多核cpu的结论,之前一直以为python运行后会绑定cpu其中的一个核心现在看来并不是这个样子。第二张图就比较有意思了cpu2满载了,这又是为什么呢?
想来想去应该是linux中cpu对进程的亲和性导致的,这种亲和性是软性的并不是强制的,这也就解释了为什么第一张图中是多cpu在负载。
ok为了更直观的看出python线程能够利用多核cpu,我们改下代码,换一种方式再来看下
import os while 1: print os.getpid()#输出进程号
运行代码结果
一目了然,线程的确在不同的核心上切换。
现在我们回过头看下那句经典的话"因为GIL的存在,python的多线程不能利用多核CPU",这句话很容易让人理解成GIL会让python在一个核心上运行,有了今天的例子我们再来重新理解这句话,GIL的存在让python在同一时刻只能有一个线程在运行,这毋庸置疑,但是它并没有给线程锁死或者说指定只能在某个cpu上运行,另外我需要说明一点的是GIL是与进程对应的,每个进程都有一个GIL。
python线程的执行流程理解
线程——>抢GIL——>CPU
这种执行流程导致了CPU密集型的多线程程序虽然能够利用多核cpu时跟单核cpu是差不多的,并且由于多个线程抢GIL这个环节导致运行效率<=单线程。
看到这可能会让人产生一种错觉,有了GIL后python是线程安全的,好像根本不需要线程锁,而实际情况是线程拿到CPU资源后并不是一直执行的,python解释器在执行了该线程100条字节码(注意是字节码不是代码)时会释放掉该线程的GIL,如果这时候没有加锁那么其他线程就可能修改该线程用到的资源;
遇到IO也会释放GIL
另外一个问题是遇到IO也会释放GIL,下面是这两种情况的例子
import threading a=[] def m1(): for _ in range(100000): a.append(1) def m2(): for _ in range(100000): a.append(2) def check(): """ 检查a是否有序 """ for i in range(len(a)): if i!=0: if a<i><a[i-1]: print a[i-1],a<i> return False return True t1=threading.Thread(target=m1) t2=threading.Thread(target=m2) t1.start() t2.start() t1.join() t2.join() print check() 预期1111...22222...,截图显示跟预期的不同 import threading text1='1'*10000 text2='2'*10000 def write(text): with open('test.txt','a')as f: f.write(text) def m1(): write(text1) def m2(): write(text2) t1=threading.Thread(target=m1) t2=threading.Thread(target=m2) t1.start() t2.start() t1.join() t2.join()
test.txt截图
最后结论是,因为GIL的存在,python的多线程虽然可以利用多核CPU,但并不能让多个核同时工作。
综上所述,上述内容就给大家介绍完毕,希望可以给大家带来帮助。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/128442.html
小编写这篇文章的一个主要目的,主要是来给大家做个解答,解答的内容主要是涉及到的内容有Python解析器的一些相关介绍,介绍的内容主要是Cpython的GIL解释器解锁相关机制的一些介绍。具体的内容,下面就给大家详细解答下。 本节重点 掌握Cpython的GIL解释器锁的工作机制 掌握GIL与互斥锁 掌握Cpython下多线程与多进程各自的应用场景 本节时长需控制在45分钟内 一引子...
摘要:在一个进程内部,要同时干多件事,就需要同时运行多个子任务,我们把进程内的这些子任务称为线程。总结一下,多任务的实现方式有三种多进程模式多线程模式多进程多线程模式线程是最小的执行单元,而进程由至少一个线程组成。 进程与线程 很多同学都听说过,现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持多任务的操作系统。 什么叫多任务呢?简单地说,就是操作系统可以同时...
摘要:的解析器实现更成熟,第三方库质量高解析器尽管已经有了很大的性能提升和很多新的功能,但是从源代码实现的角度来说,基本上是通过在源代码上打来增加功能的。相对而言,解析器更成熟,也比较稳定。 最近在考虑学习一门后端语言,在ruby和python直接犹豫,然后自己做了一些对比,希望能帮到有同样问题的你。 一、异同对比选择1、Python和ruby的相同点: 都强调语法简单,都具有更一般的表达...
摘要:每个在同一时间只能执行一个线程在单核下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。在多线程下,每个线程的执行方式获取执行代码直到或者是虚拟机将其挂起。拿不到通行证的线程,就不允许进入执行。 进程与线程 并发与并行 进程与线程 首先要理解的是,我们的软件都是运行在操作系统之上,操作系统再控制硬件,比如 处理器、内存、IO设备等。操作系统为了向上...
摘要:中单线程多线程与多进程的效率对比实验多线程多进程中多线程和多进程的对比是运行在解释器中的语言,查找资料知道,中有一个全局锁,在使用多进程的情况下,不能发挥多核的优势。 title: Python中单线程、多线程与多进程的效率对比实验date: 2016-09-30 07:05:47tags: [多线程,多进程,Python]categories: [Python] meta: Pyt...
阅读 893·2023-01-14 11:38
阅读 838·2023-01-14 11:04
阅读 708·2023-01-14 10:48
阅读 1894·2023-01-14 10:34
阅读 903·2023-01-14 10:24
阅读 754·2023-01-14 10:18
阅读 482·2023-01-14 10:09
阅读 523·2023-01-14 10:02