5

我有一个“我只想理解它”的问题。首先,我在 Ubuntu 上使用 python 2.6.5。

所以..python中的线程(通过线程模块)只是“线程”,只是告诉GIL在某个时间段内从每个“线程”运行代码块等等......实际上并没有真正的线程在这里..

所以问题是 - 如果我在一个线程中有一个阻塞套接字,现在我正在发送数据并将线程阻塞 5 秒。我希望阻塞所有程序,因为它是一个sock.send阻塞线程的 C 命令 ()。但令我惊讶的是,主线程继续运行。所以问题是 - GIL 在到达像发送这样的阻塞命令后如何能够继续并运行其余代码?不是必须在这里使用真正的线程吗?

谢谢。

4

3 回答 3

12

Python 使用“真正的”线程,即底层平台的线程。在 Linux 上,它将使用 pthread 库(如果您有兴趣,这里是实现)。

Python 线程的特别之处在于 GIL:一个线程只有持有这个全局锁才能修改 Python 数据结构。因此,许多 Python 操作无法使用多个处理器内核。但是,带有阻塞套接字的线程不会持有 GIL,因此它不会影响其他线程。

GIL 经常被误解,使人们相信线程在 Python 中几乎没有用处。GIL 唯一阻止的是在多个处理器内核上同时执行“纯”Python 代码。如果您使用线程使 GUI 响应或在阻塞 I/O 期间运行其他代码,GIL 不会影响您。如果您使用线程在多个处理器内核上同时运行某些 C 扩展(如 NumPy/SciPy)中的代码,则 GIL 也不会影响您。

于 2011-02-07T12:02:10.443 回答
6

GIL 上的Python wiki 页面提到

请注意,潜在的阻塞或长时间运行的操作(例如I/O、图像处理和 NumPy 数字运算)发生在 GIL 之外。

于 2011-02-07T11:30:43.203 回答
5

GIL(全局解释器锁)只是一个锁,它本身不运行任何东西。相反,Python 解释器会根据需要捕获并释放该锁。通常,在运行 Python 代码时会持有锁,但会在调用较低级别的函数(例如sock.send)时释放。由于 Python 线程是真正的 OS 级线程,线程不会并行运行 Python 代码,但如果一个线程调用一个长时间运行的 C 函数,则释放 GIL,另一个 Python 代码线程可以运行,直到第一个线程完成。

于 2011-02-07T12:22:07.393 回答