jer*_*ahd 84 python multithreading
我一直试图围绕线程如何在Python中运行,并且很难找到有关它们如何运行的良好信息.我可能只是错过了一个链接或东西,但似乎官方文档在这个主题上不是很彻底,我找不到一个好的写作.
据我所知,一次只能运行一个线程,活动线程每10个指令左右切换一次?
哪里有一个很好的解释,或者你可以提供一个?了解在使用Python线程时遇到的常见问题也是非常好的.
Pet*_*ann 51
是的,因为全局解释器锁(GIL),一次只能运行一个线程.以下是一些关于此的一些见解的链接:
从最后一个链接有趣的引用:
让我解释一下这意味着什么.线程在同一虚拟机内运行,因此在同一台物理机器上运行.进程可以在同一物理计算机或另一台物理计算机上运行.如果围绕线程构建应用程序,则无法访问多台计算机.因此,您可以扩展到单台计算机上的核心数量(随着时间的推移会有很多核心),但要真正达到网络规模,您无论如何都需要解决多机器问题.
如果要使用多核,则pyprocessing定义基于进程的API以进行实际并行化.该PEP还包括了一些有趣的基准.
mma*_*tax 20
下面是一个基本的线程示例.它会产生20个线程; 每个线程都会输出其线程号.运行它并观察它们的打印顺序.
import threading
class Foo (threading.Thread):
def __init__(self,x):
self.__x = x
threading.Thread.__init__(self)
def run (self):
print str(self.__x)
for x in xrange(20):
Foo(x).start()
Run Code Online (Sandbox Code Playgroud)
正如您所暗示的那样,Python线程是通过时间切片实现的.这就是他们获得"平行"效果的方式.
在我的示例中,我的Foo类扩展了线程,然后我实现了该run方法,这是您希望在线程中运行的代码所在的位置.要启动线程,请调用start()线程对象,这将自动调用run方法...
当然,这只是非常基础.您最终希望了解用于线程同步和消息传递的信号量,互斥锁和锁定.
注意: 无论我在何处提及,thread我的意思是在明确声明之前专门在python中使用线程。
如果您来自C/C++后台,线程在python中的工作方式会有所不同。在python中,给定时间只能有一个线程处于运行状态,这意味着python中的线程无法真正利用多个处理内核的功能,因为根据设计,线程不可能在多个内核上并行运行。
由于python中的内存管理不是线程安全的,因此每个线程都需要对python解释器中的数据结构进行独占访问。此独占访问是通过一种称为(全局解释器锁)的机制获得的。GIL
Why does python use GIL?
为了防止多个线程同时访问解释器状态并破坏解释器状态。
这个想法是,每当执行一个线程时(即使它是主线程),都会获取一个GIL,并且在某个预定义的时间间隔后,当前线程会释放GIL,而其他某个线程(如果有)会重新获取GIL。
Why not simply remove GIL?
删除GIL并不是不可能的,只是这样做的目的是,我们最终将多个锁放入解释器中以序列化访问,这甚至使单线程应用程序的性能降低。
因此删除GIL的成本是通过降低单线程应用程序的性能来弥补的,这是从未希望的。
So when does thread switching occurs in python?
GIL释放时发生线程切换。那么GIL何时释放?有两种情况需要考虑。
如果线程正在执行CPU绑定操作(Ex图像处理)。
在旧版本的python中,线程切换通常在固定数量的python指令之后发生,默认情况下设置为。100由于执行一条指令所花费的时间,决定何时应该进行切换并不是一个很好的策略可能从毫秒到一秒甚至很疯狂。因此,每条100指令之后释放GIL 而不管它们执行的时间是一个糟糕的策略。
在新版本中,不是使用指令计数作为切换线程的度量标准,而是使用了可配置的时间间隔。默认的切换间隔是5毫秒。您可以使用来获取当前的切换间隔sys.getswitchinterval()。可以使用更改sys.setswitchinterval()
如果线程正在执行某些IO绑定操作(例如文件系统访问或
网络IO)
每当线程等待某些IO操作完成时,就会释放GIL。
Which thread to switch to next?
解释器没有自己的调度程序。在间隔结束时调度哪个线程是操作系统的决定。。
| 归档时间: |
|
| 查看次数: |
38752 次 |
| 最近记录: |