Python并发编程

发布于 2017-07-16 · 本文总共 1562 字 · 阅读大约需要 5 分钟

在Python中如何实现多线程?

一个线程就是一个轻量级进程,多线程能让我们一次执行多个线程。 Python是多线程语言,其内置有多线程工具包。 Python中的GIL(全局解释器锁)确保一次执行单个线程。 一个线程保存GIL并在将其传递给下个线程之前执行一些操作,这会让我们产生并行运行的错觉。 但实际上,只是线程在CPU上轮流运行。 当然,所有的传递会增加程序执行的内存压力。

GIL

尽管Python完全支持多线程编程,但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势(比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。

GIL并不是Python的特性,Python完全可以不依赖于GIL!!!!

GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。 有名的编译器例如GCC,INTEL C++,Visual C++等。 Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。 然而因为CPython是大部分环境下默认的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.)

python的代码执行由python虚拟机(也叫解释器主循环,CPython版本)来控制,python在设计之初就考虑到在解释器的主循环中,同时只有一个线程在运行。 即在任意时刻只有一个线程在解释器中运行。 对python虚拟机访问的控制由全局解释锁GIL控制,正是这个锁来控制同一时刻只有一个线程能够运行。

py在同一时刻只能跑一个线程,这样在跑多线程的情况下,只有当线程获取到全局解释器锁后才能运行,而全局解释器锁只有一个,因此即使在多核的情况下也只能发挥出单核的功能。 Guido van Rossum 在创造python的时候,上世纪90年代,多核cpu完全属于不可想象的, 现在由于硬件发展速度太快,程序编写就要考虑用尽cpu的全部性能,否则就要被淘汰,那么对于python同样也要如此。

GIL的设计简化了CPython的实现,使得对象模型,包括关键的内建类型如字典,都隐式可以并发访问。锁住全局解释器使得其比较容易的实现对多线程的支持

GIL锁: 保证同一时刻只有一个线程能使用到cpu 互斥锁: 多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱

解决办法

1.如果你完全工作于Python环境中,你可以使用 multiprocessing 模块来创建一个进程池,并像协同处理器一样的使用它。

import multiprocessing
pool = multiprocessing.Pool()

2.使用C扩展编程技术。 主要思想是将计算密集型任务转移给C,跟Python独立,在工作的时候在C代码中释放GIL




本博客所有文章采用的授权方式为 自由转载-非商用-非衍生-保持署名 ,转载请务必注明出处,谢谢。
声明:
本博客欢迎转发,但请保留原作者信息!
博客地址:邱文奇(qiuwenqi)的博客;
内容系本人学习、研究和总结,如有雷同,实属荣幸!
阅读次数:

文章评论

comments powered by Disqus


章节列表