Python 到底是 线程快 还是 进程快

Python 到底是 线程快🚀 还是 进程快🚀

前言

在探究这个 Python 中 到底是 线程快 还是 进程快 前,有必要先了解一下CPython的GIL锁,这非常重要,关系到线程调用的机制,以及Python运行速度慢的原因之一

GIL全局解释器锁

GIL 全称 Global Interpreter Lock,中文释义 全局解释器锁,得先知道的是,这不是Python独有的特性,它只是在实现CPython(Python解释器)时,引入的一个概念

官方对此的描述

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)

中文翻译

在CPython中,全局解释器锁或GIL是互斥锁,可防止多个
本地线程一次执行Python字节码。 这个锁主要是必要的
因为CPython的内存管理不是线程安全的。 (但是,自GIL
存在,其他功能也越来越依赖于它所执行的保证。)

简单的来说,就是在Cpython解释器中,同一个进程下开启多线程,由于GIL是一个互斥锁(mutex),阻止了多个线程在同一个进程内的同时执行,同一时刻的同一进程只能有一个线程在执行,毫无疑问,这降低了执行效率,那为什么还要有GIL的存在呢,要明白GIL的必要性,就需要了解CPython对于线程安全的 内存管理机制

线程快 还是 进程快 这得看应用场景,这里直接说答案,对于 计算密集型 的任务来说,多进程更快对于 IO密集型 的任务来说,多线程更快


IO密集型

IO 是 Input/Output 的缩写,说白就是 对数据对读取和写入,那IO密集型,就是大部分在对数据 读取和写入 的程序系统(硬盘读写、网络传输等)

之前提到了由于 GIL全局解释器锁 的存在,同一时刻同一进程中只有一个线程在执行,对于这种想要等的IO操作来说,开再多的进程效果也不大,且开进程的开销较大,还不如多开线程,效率反而高点

性能测试
对于IO密集型程序来说,多线程下和多进程下的分别耗时统计

多进程

from multiprocessing import Process


class MyProcess(Process):

    def sleep(self):
        print(f"{self.name} 正在执行")
        time.sleep(2)

    def run(self) -> None:
        self.sleep()


if __name__ == '__main__':
    start_time = time.time()
    pro_list = []
    for i in range(10):
        p = MyProcess()
        p.start()
        pro_list.append(p)

    for i in pro_list:
        i.join()
    print(f"耗费时间: {time.time() - start_time}")

开启十个进程下,耗时为:2.734959363937378(每次运行不一样很正常,这里仅作参考)

多线程

from threading import Thread


class MyProcess(Thread):

    def sleep(self):
        print(f"{self.name} 正在执行")
        time.sleep(2)

    def run(self) -> None:
        self.sleep()


if __name__ == '__main__':
    start_time = time.time()
    thr_list = []
    for i in range(10):
        t = MyProcess()
        t.start()
        thr_list.append(t)

    for i in thr_list:
        i.join()
    print(f"耗费时间: {time.time() - start_time}")

开启十个线程下,耗时为:2.0112526416778564(每次运行不一样很正常,这里仅作参考)


计算密集型

程序系统大部分在做 数据计算、逻辑判断、循环等,为计算密集型,比如:1+2+3…+10000000

虽然说由于 GIL全局解释器锁 的存在,用不到真正的多线程,但可以开多进程呀,随着cpu的增多执行效率肯定会有所提高,但有种特殊情况是,然后电脑只有单核的情况下,没有多核来并行计算,徒增了创建进程的开销,多进程对单核来说不管用,不过话说回来,都已经这个时代了,单核的电脑我是没再见到过🤣

性能测试
对于计算密集型程序来说,多线程下和多进程下的分别耗时统计

多进程

class MyProcess(Process):

    def sleep(self):
        print(f"{self.name} 正在执行")
        num = 0
        while num < 10000000:
            num += 1

    def run(self) -> None:
        self.sleep()


if __name__ == '__main__':
    start_time = time.time()
    pro_list = []
    for i in range(10):
        p = MyProcess()
        p.start()
        pro_list.append(p)

    for i in pro_list:
        i.join()
    print(f"耗费时间: {time.time() - start_time}")

开启十个线程下,耗时为:1.843491792678833(每次运行不一样很正常,这里仅作参考)

多线程

class MyProcess(Thread):

    def sleep(self):
        print(f"{self.name} 正在执行")
        num = 0
        while num < 10000000:
            num += 1

    def run(self) -> None:
        self.sleep()


if __name__ == '__main__':
    start_time = time.time()
    thr_list = []
    for i in range(10):
        t = MyProcess()
        t.start()
        thr_list.append(t)

    for i in thr_list:
        i.join()
    print(f"耗费时间: {time.time() - start_time}")

开启十个线程下,耗时为:3.725153923034668(每次运行不一样很正常,这里仅作参考)


相关博客

Python threading 开启线程

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值