`
san_yun
  • 浏览: 2653258 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

线程安全及Python中的GIL

 
阅读更多

 

对于Python 的GIL和线程安全 很多人不是很了解,通过本文,希望能让大家对Python 的GIL等内容有所帮助。本文还将就主要谈下笔者对线程安全 的一些理解。

 

你的PC或者笔记本还是单核吗? 如果是,那你已经out了.随着纳米技术的不断进步, 计算机芯片的工艺也在进步,但是已经很难在工艺上的改进来提高 运算速度而满足 摩尔定理, 所以intel, amd相继在采用横向的扩展即增加更多的CPU, 从而双核, 4核, N核不断推出,于是我们进入了多核时代.于是一个问题出现了, 多核时代的出现对于我们程序员而言意味着什么, 我们如何利用多核的优势?

 

在回答这个问题之前,建议对 进程 和 线程 不熟悉的读者可以先补下相关的知识.当然方案是,可以采用 多进程, 也可以采用 多线程. 二者的最大区别就是, 是否共享资源, 后者是共享资源的,而前者是独立的. 所以你也可能想起了google chrome为什么又开始使用独立的进程 来作为每个tab服务了(不共享数据,意味着有更好的安全性).相对于进程的轻型特征,多线程环境有个最大的问题就是 如何保证资源竞争,死锁, 数据修改等.于是,便有了 线程安全 (thread safety)的提出.

 

线程安全

Thread safety is a computer programming concept applicable in the context of multi-threaded programs. A piece of code is thread-safe if it functions correctly during simultaneous execution by multiple threads.In particular, it must satisfy the need for multiple threads to access the same shared data,and the need for a shared piece of data to be accessed by only one thread at any given time.

 

上面是wikipedia中的解释, 换句话说, 线程安全 是在多线程的环境下, 线程安全能够保证多个线程同时执行时程序依旧运行正确, 而且要保证对于共享的数据,可以由多个线程存取,但是同一时刻只能有一个线程进行存取.既然,多线程环境下必须存在资源的竞争,那么如何才能保证同一时刻只有一个线程对共享资源进行存取?加锁, 对, 加锁可以保证存取操作的唯一性, 从而保证同一时刻只有一个线程对共享数据存取.通常加锁也有2种不同的粒度的锁:

 

fine-grained(所谓的细粒度), 那么程序员需要自行地加,解锁来保证线程安全

coarse-grained(所谓的粗粒度), 那么语言层面本身维护着一个全局的锁机制,用来保证线程安全

 

前一种方式比较典型的是 java, Jython 等, 后一种方式比较典型的是 CPython (即Python).

前一种本文不进行讨论, 具体可参考 java 中的多线程编程部分.

至于Python中的全局锁机制,也即 GIL (Global Interpreter Lock), 下面主要进行一些讨论.

 

Python的GIL

什么是GIL ? 答案可参考wikipedia中的说明, 简单地说就是:

每一个interpreter进程,只能同时仅有一个线程来执行, 获得相关的锁, 存取相关的资源.那么很容易就会发现,如果一个interpreter进程只能有一个线程来执行, 多线程的并发则成为不可能, 即使这几个线程之间不存在资源的竞争.从理论上讲,我们要尽可能地使程序更加并行, 能够充分利用多核的功能, 那么Python为什么要使用 全局的GIL 来限制这种并行呢?这个问题,其实已经得到了很多的讨论, 不止十年, 可以参考下面的文档:

 

反对GIL的声音:

An open letter to Guido van Rossum (这个文章值得一看,下面有很多的留言也值得一看)

认为GIL不能去除的:

It isn't Easy to Remove the GIL (这个文章来自python作者 Guido, 他说明了什么要使用 GIL)其它的一些讨论很容易从Google来搜索得到, 譬如: GIL at google.那么,简单总结下双方的观点.认为应该去除GIL的:不顺应计算机的发展潮流(多核时代已经到来, 而 GIL 会很影响多核的使用)大幅度提升多线程程序的速度认为不应该去除GIL 的(如果去掉,会):写python的扩展(module)时会遇到锁的问题,程序员需要繁琐地加解锁来保证线程安全会较大幅度地减低单线程程序的速度后者是Guido最为关切的, 也是不去除GIL最重要的原因, 一个简单的尝试是在1999年(十年前), 最终的结果是导致单线程的程序速度下降了几乎2倍.

归根结底,其实就是多进程与多线程的选择问题, 有一段话比较有意思, 可以参考 http://www.artima.com/forums/flat.jsp?forum=106&thread=214235.

 

我引用如下:

I actually don't think removing the GIL is a good solution.

But I don't think threads are a good solution, either.

They're too hard to get right, and I say that after spending literally years studying threading in both C++ and Java.

Brian Goetz has taken to saying that no one can get threading right.

引自Bruce Eckel 对Guido 的回复. 而Bruce Eckel 是何许人, 如果你了解Java 或者C++, 那么应该不会不知道他.

 

个人的观点

那么,从我自己的角度来看(我没有太多的多线程编程经验), 先不论多线程的速度优势等,我更加喜欢多进程的是:简单,无需要人为(或者语言级别)的加解锁. 想想 java 中的多线程编程,程序员通常会在此处出错(Java程序员可以思考下)安全, 这也是浏览器为什么开始使用多进程的一个原因依照Python自身的哲学, 简单 是一个很重要的原则,所以, 使用 GIL 也是很好理解的.

当然你真的需要充分利用多核的速度优势,此时python可能并非你最佳的选择,请考虑别的语言吧,如Java, erlang 等.

 

 

分享到:
评论

相关推荐

    线程安全及Python中的GIL原理分析

    本文讲述了线程安全及Python中的GIL。分享给大家供大家参考,具体如下: 摘要 什么是线程安全? 为什么python会使用GIL的机制? 在多核时代的到来的背景下,基于多线程来充分利用硬件的编程方法也不断发展起来, 但是...

    《再谈Python的GIL》测试用例

    Python的全局解释器锁(Global Interpreter Lock,简称GIL)是Python编程中一个重要的概念,尤其是在多线程编程中。GIL的存在是为了保护Python的内存管理机制,避免在多线程环境下出现数据竞争的问题。然而,这也...

    使用进程池规避Python的GIL限制

    Python中的全局解释器锁(GIL)是一个经常被提及的特性,它对多线程的CPU密集型程序有一定的影响。要理解如何规避GIL限制,我们首先需要了解GIL是什么,以及它为何会成为性能瓶颈,之后再探讨通过进程池来绕过GIL...

    python GIL详细解释

    在深入解释Python GIL之前,我们需要了解几个关键概念,首先是Python线程的概念,其次是Python中的多线程为何受限制,以及GIL是如何对多线程程序性能产生影响的。 ### Python线程概念 Python中的线程,实际上是由...

    Inside the Python GIL

    全局解释锁(Global Interpreter Lock,简称GIL)是Python中的一个重要概念,它在解释器层面上限制了多线程程序利用多核处理器的能力。GIL的存在引发了广泛的讨论与争议,尤其是在探讨Python并发编程时。本文将详细...

    Python中GIL的使用详解

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

    Python应用实战:python多线程-多线程安全问题&lock与rlock.zip

    在Python中,由于全局解释器锁(GIL)的存在,Python的多线程并不能实现真正的并行计算,但仍然可能遇到线程安全问题,如数据竞争、死锁等。 数据竞争是多线程环境中常见的问题,当两个或多个线程同时访问并修改...

    Python threading 5 不一定有效率 GIL (多线程 教学教程tutorial)

    Python_threading_5_不一定有效率_GIL_(多线程_教学教程tutorial)

    gil.gilgil

    全局解释器锁是Python解释器为了保证线程安全而引入的一个机制,它确保任何时候只有一个线程执行Python字节码。在多线程环境下,这限制了并行执行的能力,因为即使在多核处理器上,Python也无法利用所有核心进行并发...

    Python GIL解析

    全球解释器锁(Global Interpreter Lock,简称GIL)是Python解释器为了确保线程安全而采取的一种机制。在多线程环境中,GIL的存在使得同一时刻只有一个线程能够执行Python字节码。这种设计在单核处理器时代有效地...

    inside the python gil

    GIL的存在对于某些类型的应用程序来说是非常重要的,因为它简化了线程模型,并使得C语言扩展可以安全地与Python交互。然而,它也带来了一些显著的负面影响,尤其是在多核处理器环境下: 1. **多线程性能瓶颈**:...

    python 线程的使用 python线程基础知识,提供python2示例代码,供参考学习

    需要注意的是,Python中的全局解释器锁(GIL)使得在同一时刻,即使在多核处理器上,Python的线程也无法实现真正的并行计算。这限制了Python在计算密集型任务中的性能,但在I/O密集型任务中,由于线程可以在等待I/O...

    深入学习python多线程与GIL

    GIL是为了保证内存管理的一致性而引入的,因为Python的内存管理不是线程安全的。每个Python线程在执行字节码时必须持有GIL,这确保了在任何时候只有一个线程在执行Python代码,即使是在多核处理器上也是如此。 在...

    PYthon-multithreading-Test.rar_python_python 多线程_python多线程_多线程

    多线程并非总是性能提升的关键,由于GIL(全局解释器锁)的存在,Python的多线程在CPU密集型任务上并不能充分利用多核优势。此时,可以考虑使用多进程(`multiprocessing`模块)或者异步IO(`asyncio`模块)来实现...

    Python GIL资料(深入理解GIL)

    Python语言的全局解释锁GIL详解,由David Beazley写的文档,分析了单核CPU、多核CPU下的Python多线程的效率,并分析线程调度,CPU竞争,以及在NEW GIL等内容,相信看完后会对Python的GIL有一个深入的理解。

    python多线程编程实现网络串口透传

    在Python多线程编程中,需要注意GIL(全局解释器锁)的存在,虽然Python的多线程在CPU密集型任务上可能表现不佳,但在I/O密集型任务(如网络和串口通信)中,由于线程间等待I/O的时间较长,多线程仍能有效提高程序...

    python多线程学习

    - **全局解释器锁(GIL)**:Python的CPython实现中存在GIL,这使得在同一时刻只有一个线程能够执行Python字节码,即使在多核处理器系统中,也限制了多线程并行执行的能力。因此,Python更适合于I/O密集型任务而不是...

Global site tag (gtag.js) - Google Analytics