- 线程是操作系统进行计算和调度的最小的单位,程序运行在这里, 每一个线程有属于自己的上下文。
- 进程是比线程更大一点的单位, 每个进程有自己的内存之类的,每个进程有好几个线程,共享内存,就是可以读写同样的变量。
GIL
-
当一个进程中有若干个线程的时候就会有racing竞争冒险,因为若干个线程有可能同时运行,也有可能交替运行,没有办法控制相对顺序。
-
举例: 两个线程运行下面的程序
a = 1
if a>0:
a-=1
- 在python中不用申请内存,也不用释放内存, 因为里面有memory mangement(内存管理)帮我们做了这件事。
- reference count引用计数, 每一个object都数着那个地方用到了自己,用一次加一,不用了就-1, 当我的引用计数为0的时候就释放掉这快内存。
- 底层有一个c代码的–ob_refcnt, 但是这个–也不是atomic不可被打断的,–看起来是一个操作符,但其实是把refcnt的值读出来,-1 , 再存回去。在这中间就有可能有线程过来在你存回去之前操作,就数乱了,就没办法保证每一个的object被正确的释放,就会导致内存泄漏。
- 所以python加了一个全局解释器锁,GIL,优点
- 非常简单,相对于给每一个object加一个锁,加一个全局锁非常的简单。
- 然后只有一个锁,就避免了死锁的问题。
- 对于单线程或者是没有办法并行的多线程是非常优秀的。
- 对于写c extension的时候容易很多,没有内存泄漏的问题,不用管很多锁,第三方编程编的容易。
- 缺点
- 上世纪90年代初期,多核几乎不存在,多线程存在的原因是,可以轮流执行,不会因为某一个线程计算过大,而导致卡住的问题。
- 没办法利用cpu的多核优势。
- 避开这个问题
- 用多进程mutil processing来用多核优势。