python多线程对多核cpu的利用解析

 更新时间:2022年07月01日 11:13:39   作者:挪威的森林s  
这篇文章主要为大家介绍了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] &lt; 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,但并不能让多个核同时工作。

以上就是python多线程对多核cpu的利用解析的详细内容,更多关于python多线程利用多核cpu的资料请关注脚本之家其它相关文章!

相关文章

  • Python读取hdf文件并转化为tiff格式输出

    Python读取hdf文件并转化为tiff格式输出

    这篇文章主要介绍了Python读取hdf文件并转化为tiff格式输出,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • Python面向对象的程序设计详情

    Python面向对象的程序设计详情

    这篇文章主要介绍了Python面向对象的程序设计详情,面向对象的程序设计在Python中具有非常重要的地位,熟练的使用面向对象编程能够为我们的Python编程提供很多的便利之处,希望您阅读完本文后能够有所收获
    2022-01-01
  • python装饰器简介及同时使用多个装饰器的方法

    python装饰器简介及同时使用多个装饰器的方法

    这篇文章主要介绍了python装饰器简介及同时使用多个装饰器的方法,python支持一个函数同时使用多个装饰器,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • 解决jupyter notebook显示不全出现框框或者乱码问题

    解决jupyter notebook显示不全出现框框或者乱码问题

    这篇文章主要介绍了解决jupyter notebook显示不全出现框框或者乱码问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • python程序运行进程、使用时间、剩余时间显示功能的实现代码

    python程序运行进程、使用时间、剩余时间显示功能的实现代码

    这篇文章主要介绍了python程序运行进程、使用时间、剩余时间显示功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2019-07-07
  • pycharm安装汉化包失败的问题及解决

    pycharm安装汉化包失败的问题及解决

    这篇文章主要介绍了pycharm安装汉化包失败的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Python3+Pycharm+PyQt5环境搭建步骤图文详解

    Python3+Pycharm+PyQt5环境搭建步骤图文详解

    这篇文章主要介绍了Python3+Pycharm+PyQt5环境搭建步骤图文详解,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • Zabbix实现微信报警功能

    Zabbix实现微信报警功能

    这篇文章主要介绍了Zabbix实现微信报警的相关资料,本文图文并茂介绍的非常详细,需要的朋友可以参考下
    2016-10-10
  • Python利用flask sqlalchemy实现分页效果

    Python利用flask sqlalchemy实现分页效果

    这篇文章主要为大家详细介绍了利用flask sqlalchemy实现分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • python正则表达式re.match()匹配多个字符方法的实现

    python正则表达式re.match()匹配多个字符方法的实现

    这篇文章主要介绍了python正则表达式re.match()匹配多个字符方法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论