SAE Python Blog

在SAE 上学习使用Python ...

↑我也要推荐

《Python源码剖析》读书笔记:多线程

发布时间:2011-10-27 00:22:33, 关注:+5756, 赞美:+7, 不爽:+3

本文标签: gil 多线程 python源码研究

原始出处: 不沉之月

(如无特别注明,以下笔记都是基于Linux平台)

  • GIL覆盖面不只是Python的解释器,还包括Python的C API
  • Python线程根据”已执行指令数”来切换线程,在Python 2.5+,这个阈值是100

>>> import sys
>>> sys.getcheckinterval()
100

但有些字节码指令执行并不会增加这个计数,因此线程切换时已执行指令数可能会比这个略多
** 当字节码执行之后通过goto转移到fast_next_opcode,这时不会更新计数器
** 线程通过阻塞调度,并不会重置计数器

  • GIL并不是随着解释器启动而创建的,只有用户第一次使用thread的时候创建。
  • 在不同平台上GIL使用不同的实现,在Linux使用信号量。
  • 创建线程使用pthread库,Python线程是使用系统原生线程。
  • 子线程创建后马上申请GIL
  • PyThreadState保存了这个线程的上下文信息
  • 当一个活动线程挂起后,调度到哪个线程由操作系统线程调度决定。当前活动线程挂起前,会释放GIL

  • Python线程调度有两种方式,一种是标准调度,另一种是阻塞调度。
    ** 标准调度是当前线程已执行指令数大于100时主动释放GIL,让其他线程有机会运行。
    ** 阻塞调度是当前线程执行到阻塞的系统调用(例如time.sleep)之前,释放GIL,让其他线程有机会运行。

  • thread模块提供基础的Lock对象,默认使用信号量,如果在信号量有问题的情况下,使用pthread_lock

  • 当前线程对Lock对象加锁前,先释放GIL,获得锁后再获取GIL。(Threadmodule.c:38)
  • threading模块是Python写成的。里面的RLock/Condition/Semaphore/Event锁对象都是基于thread.Lock
  • threading模块的Thread启动分两步,第一步使用thread.start_new_thread创建原生线程,原生线程执行__bootstrap函数,此时线程状态为创建中,放入_limbo字典;第二步在__bootstrap函数中将自己放到_active字典,以线程ID为key,、然后执行run函数

PS: 求购正版《Python源码剖析》,或求提供陈儒联系方式,谢谢!

如果你觉得本站对你有帮助,欢迎向本站赞助 :P

使用支付宝捐赠

Copyright© Python4cn(news, jobs) simple-is-better.com, 技术驱动:powered by web.py 空间主机:Webfaction

版权申明:文章转载已注明出处,如有疑问请来信咨询。本站为 python 语言推广公益网站,与 python 官方没有任何关系。

联系/投搞/留言: en.simple.is.better@gmail.com 向本站捐赠