首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。
那么CPython实现中的GIL又是什么呢?GIL全称Global Interpreter Lock为了避免误导,我们还是来看一下官方给出的解释:
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.)
GIL是Python解释器中的全局锁(Global Interpreter Lock),它是一种机制,确保同一时刻只有一个线程在执行Python代码。在多线程程序中,因为GIL的存在,多个线程并不能真正并行地执行,而是通过竞争GIL的方式来实现对CPU的占用。这也是为什么Python中的多线程程序并不比单线程程序更快的原因之一。
以下是一个简单的示例代码,演示了GIL的作用:
import threading # 全局变量 count = 0 # 线程函数 def add(): global count for i in range(1000000): count += 1 # 创建两个线程 t1 = threading.Thread(target=add) t2 = threading.Thread(target=add) # 启动线程 t1.start() t2.start() # 等待线程结束 t1.join() t2.join() # 输出结果 print("count = ", count)
在这个示例中,我们创建了两个线程,每个线程都会执行一个简单的循环,将计数器count加1,循环1000000次。如果Python中没有GIL的话,我们期望最终的count值应该是2000000。然而,实际运行的结果很可能会小于这个值,因为两个线程在竞争GIL的时候,只有一个线程能够真正地执行Python代码,而另一个线程则会被阻塞,等待GIL的释放。这导致了多线程执行时的性能瓶颈。
需要注意的是,GIL只存在于CPython解释器中,因此其他解释器,如Jython、IronPython、PyPy等,则不存在GIL的问题。
问题内容: 我总是像这样阅读代码来计算时间: 您能在这里解释什么是“%”吗? 我认为,“%”总是用于替换字符串中的某些内容,例如%s表示替换字符串,%d替换数据,但是我不知道这种情况。 问题答案: 是ipython的魔术函数,可用于计时特定代码段(单个执行语句或单个方法)。 从文档: %timeit 要使用它,例如,如果我们想确定using是否比using更快,则只需执行以下操作: 您将获得他们的
本文向大家介绍python中的iterweekdays()是什么?,包括了python中的iterweekdays()是什么?的使用技巧和注意事项,需要的朋友参考一下 iterweekdays()方法。该方法返回将用于一周的工作日数字的迭代器。 示例 输出结果 要么 输出结果
本文向大家介绍python中的itermonthdates()是什么?,包括了python中的itermonthdates()是什么?的使用技巧和注意事项,需要的朋友参考一下 itermonthdates()方法将返回该月的所有天,以及返回一个完整星期所需的月初或月末之后的所有天。 示例 输出结果 重要的是要记住 查看日历显示的输出,从上个月的日期开始,到下个月的日期结束。
本文向大家介绍python中的itermonthdays2()是什么?,包括了python中的itermonthdays2()是什么?的使用技巧和注意事项,需要的朋友参考一下 itermonthdays2()。类似于,返回的天数为元组(即,由天数和工作日数组成)。此方法用于获取一年中月份的迭代器。 示例 输出结果
问题内容: 元类是什么,我们将它们用于什么? 问题答案: 元类是类的类。类定义类的实例(即对象)的行为,而元类定义类的行为。类是元类的实例。 虽然在Python中你可以对元类使用任意可调用对象(例如Jerub演示),但是更好的方法是使其成为实际的类。是Python中常见的元类。它本身是一个类,并且是它自己的类型。你将无法纯粹使用Python 重新创建类似的东西,但是Python有点作弊。要在Pyt
问题内容: 什么是%在计算?我似乎无法弄清楚它的作用。 例如,它算出计算的百分比吗:显然等于0。如何? 问题答案: (取模)运算符从第一个参数除以第二个参数得出余数。首先将数字参数转换为通用类型。右零参数引发ZeroDivisionError异常。参数可以是浮点数,例如3.14%0.7等于0.34(因为3.14等于4 * 0.7 + 0.34。)模运算符始终产生与第二个操作数具有相同符号的结果(或
问题内容: 我正在看一些使用该符号的Python代码,但我不知道它的作用。我也不清楚要搜索的内容,因为搜索Python文档时会发现该符号,否则Google不会返回相关结果。 问题答案: 行首的符号用于类,函数和方法修饰符。 在这里阅读更多: PEP 318: Decorators Python Decorators 你会遇到的最常见的Python装饰器是: @property @classmeth
问题内容: 我试图在Python 3.3中使用旧的库(可追溯至2003年!)。当我导入它时,Python抛出错误,因为源文件中有符号,例如: 我猜这是该语言现在被放弃的标志。 它到底是什么意思,我应该用哪个(较新的)符号代替? 问题答案: 这意味着不等于。它取自(python的前身)此处: 订单测试(表示 “不等于” ) 我相信它是从Pascal那里获得的,Pascal是Guido开始使用的语言。