1、全局解释器锁
#Python代码的执行由Python虚拟机(解释器主循环)控制。Python在设计之处就考虑到在主循环中只能有一个线程执行,虽然Python解释器中可以“运行”多个线程,但是在任意时刻只有一个线程在解释器中运行。
#Python虚拟机的访问由全局解释器锁(GIL)控制,这个锁能保证同一时刻只有一个线程运行。
#在多线程环境下,Python虚拟机按以下方式执行:
①、设置GIL。
②、切换到一个线程运行。
③、运行指定数据的字节码指令或线程主动让出控制(可以调用time.sleep(0))。
④、把线程设置为睡眠状态。
⑤、解锁GIL。
⑥、再次重复以下所有步骤。
#在调用外部代码(如C/C++扩展函数)时,GIL将被锁定。直到这个函数结束为止(由于在此期间没有运行Python的字节码,因此不会做线程切换),编写扩展的程序员可以主动解锁GIL。
2、退出线程
#当一个线程结束计算,他就退出了。线程可以调用——thread.exit()等退出函数,也可以使用Python退出线程的标准方法(如sys.exit()或抛出一个SystemExit异常),不过不可以直接“杀掉(kill)”一个线程。
#不建议使用_thread模块。很明显的一个原因是,当主线程退出时,其他线程如果没有被清除就会退出。另一个模块threading能确保所有“重要的”子线程都退出后,进程才会结束。
3、Python的线程模块
#Python提供了几个用于多线程编程的模块,包括_thread、threading和Queue等。_thread和threading模块允许程序员创建和管理线程。_thread模块提供了基本线程和锁的支持,threading提供了更高级别、功能更抢的线程管理功能。Queue模块允许用户创建了一个可以用于多个线程之间共享数据的队列数据结构。
#避免使用_thread模块,原因有3点。首先,更高级别的threading模块更为先进,对线程的支持更为完善,而且使用_thread模块里的属性有可能与threading冲突;其次,低级别的_thread模块的同步原语很少(实际只有一个),而threading模块有很多;再者,_thread模块中在主线程结束时,所有线程都会被强制结束,没有警告也不会有正常清除工作,至少threading模块能确保重要子线程退出后进程才会退出。