码迷,mamicode.com
首页 > 编程语言 > 详细

python多线程

时间:2019-09-13 15:26:25      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:字节码   虚拟   同事   gil   ===   并发   开始   ++   编译   

python 代码的执行由python虚拟机来控制,虚拟机访问由GIL控制,保证其同一时刻只有一条线程运行。

虽然python能运行多线程,但是因为GIL所以同一时刻只有一条线程在python解释器运行。

 

多线程下python虚拟机按以下方式执行:

1. 设置GIL

2. 切换到一条线程去运行

3. 运行:

  a. 执行python2虚拟机运行1000字节指令    或者    执行python3虚拟机运行时间15ms字节

  b. 线程主动让出控制(遭遇sleep或者IO操作也将触发)

4. 把线程设置为睡眠状态(等待状态)

5. 释放GIL

6. 再次重复上述操作

 

线程何时切换?

==========================================================

(1)一个线程无论何时开始睡眠或等待网络 I/O,其他线程总有机会获取 GIL 执行 Python 代码。这是协同式多任务处理。CPython 也还有抢占式多任务处理。如果一个线程不间断地在 Python 2 中运行 1000 字节码指令,或者不间断地在 Python 3 运行15 毫秒,那么它便会放弃 GIL,而其他线程可以运行。把这想象成有多个线程但只有一个 CPU 时的时间片可用。

(2)当执行C/C++代码时候,直到C函数执行完毕,才让出GIL。

 

让我们回顾下 Python 是如何运行的。你的程序分两个阶段运行。首先,Python文本被编译成一个名为字节码的简单二进制格式。第二,Python解释器的主回路,一个名叫 pyeval_evalframeex() 的函数,流畅地读取字节码,逐个执行其中的指令。

抢占式多任务处理

当解释器通过字节码时,它会定期放弃GIL,而不需要经过正在执行代码的线程允许,这样其他线程便能运行:默认情况下,检测间隔是1000 字节码。所有线程都运行相同的代码,并以相同的方式定期从他们的锁中抽出。在 Python 3 GIL 的实施更加复杂,检测间隔不是一个固定数目的字节码,而是15 毫秒。然而,对于你的代码,这些差异并不显著。

协同式多任务处理

当一项任务比如网络 I/O启动,而在长的或不确定的时间,没有运行任何 Python 代码的需要,一个线程便会让出GIL,从而其他线程可以获取 GIL 而运行 Python。

这种礼貌行为称为协同式多任务处理,它允许并发;多个线程同时等待不同事件。多个线程在同一时刻只能有一个执行 Python ,但一旦线程开始连接,它就会放弃 GIL ,这样其他线程就可以运行。这意味着多个线程可以并发等待套接字连接,这是一件好事。在同样的时间内它们可以做更多的工作。

python多线程

标签:字节码   虚拟   同事   gil   ===   并发   开始   ++   编译   

原文地址:https://www.cnblogs.com/7134g/p/11516880.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!