今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务并发的执行,从而缩短程序的执行时间,同时也让用户获得更好的体验。因此在当下不管是用什么编程语言进行开发,实现让程序同时执行多个任务也就是常说的“并发编程”,应该是程序员必备技能之一。为此,我们需要先讨论两个概念,一个叫进程,一个叫线程。
进程
进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据,操作系统管理所有进程的执行,为它们合理的分配资源
线程
线程就是CPU调度的执行单元
线程和进程的区别
进程:操作系统分配内存的基本单位,资源单位(如工厂里的车间)
线程:操作系统分配cpu的基本单位,执行单位(如车间里的流水线)
任何一个进程都自带一个"主"线程
python可以实现多进程和多线程,比较遗憾的一件事情是python的多线程并不能发挥cpu的多核特性。之所以如此,是因为python的解释器有一个‘全局解释器锁GIL’的东西,任何线程执行前必须先获取GIL锁。下面是Cpython解释器的官方文档,请自信翻译后食用。
“”"
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解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势
“”"
这段话的一个重点是because CPython’s memory management is not thread-safe,简单翻译就是CPython的内存管理不是线性安全的。这也就是GIL存在的原因。
下面我们试着简单推理一下为什么?
先回顾一下python的内存垃圾回收机制:
1、引用计数
2、标记清除
3、分代回收
我们可以把这样理解:python的垃圾回收机制也是由python解释器开启的解释器级别的线程,既然是线程,就能和同一进程下的别的线程一起去争夺python解释器的执行权限。
对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理,即GIL,保证python解释器同一时间只能执行一个任务的代码。
讲到这儿,是不是就有疑问了,python多线程是不是就没有用了呢?
结论别下的太早,
首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。j python就没有GIL。
在解决这个问题前先在以下结论上达成一致:
#1. cpu到底是用来做计算的,还是用来做I/O的?
#2. 多cpu,意味着可以有多个核并行完成计算,所以多核提升的是计算性能
#3. 每个cpu一旦遇到I/O阻塞,仍然需要等待,所以多核对I/O操作没什么用处
举个栗子说明:
一个工人相当于cpu,此时计算相当于工人在干活,I/O阻塞相当于为工人干活提供所需原材料的过程,工人干活的过程中如果没有原材料了,则工人干活的过程需要停止,直到等待原材料的到来。
如果你的工厂干的大多数任务都要有准备原材料的过程(I/O密集型),那么你有再多的工人,意义也不大,还不如一个人,在等材料的过程中让工人去干别的活,
反过来讲,如果你的工厂原材料都齐全,那当然是工人越多,效率越高
结论:
对计算来说,cpu越多越好,但是对于I/O来说,再多的cpu也没用
当然对运行一个程序来说,随着cpu的增多执行效率肯定会有所提高(不管提高幅度多大,总会有所提高),这是因为一个程序基本上不会是纯计算或者纯I/O,所以我们只能相对的去看一个程序到底是计算密集型还是I/O密集型,从而进一步分析python的多线程到底有无用武之地
四个任务:计算密集的任务 每个任务耗时10s
单核情况下:
多线程好一点,消耗的资源少一点
多核情况下:
开四个进程:10s多一点
开四个线程:40s多一点
四个任务:IO密集的任务 每个任务io 10s
单核情况下:
多线程好一点
多核情况下:
多线程好一点
多线程和多进程都有自己的优点,要根据项目需求合理选择
以上就是我对GIL锁的简单理解,还有疑惑可以着重看一下这篇文章。添加链接描述