1、引言/动机
多线程(MT)并行运行相互独立的子任务,提升整个任务的效率。
多线程适合的任务的特点:它们本质上是异步的,需要有多个并发事务,各个事务的运行顺序可以是不确定的,随机的,不可预测的。运算密集型的任务一般较容易分隔成多个子任务。
2、进程和线程
进程有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。
进程之间使用进程间通讯(IPC)共享信息。OS为进程公平分配时间,进程也可以通过fork和spawn操作完成其他任务。
线程(轻量级进程)所有线程运行在同一个进程中,共享相同的运行环境。线程有自己的指令指针,记录自己运行到什么地方。线程的运行可能被抢占(中断)、暂时挂起(睡眠)。一个进程中各线程间共享一片数据空间,线程之间可以方便共享数据及相互通讯。
竞态条件指多个线程共同访问同一片数据,由于数据访问的顺序不一致有可能导致数据结果的不一致的问题。线程库通过同步原语来控制线程的执行和数据的访问。
3、Python、线程和全局解释器锁
(1)全局解释器锁
Python虚拟机(也叫解释器主循环)控制Python代码执行。在主循环中,同时只有一个线程在执行。对Python虚拟机的访问由全局解释器锁(global interpreter lock,GIL)来控制。
在多线程环境中,Python虚拟机按照以下方式执行。
①设置GIL。
②切换到一个线程去执行。
③运行:a.指定数量的字节码的指令,或者b.线程主动让出控制(可以调用time.sleep(0))
④把线程设置为睡眠状态。
⑤解锁GIL。
⑥再次重复以上所有步骤。
在调用外部代码(如C/C++扩展函数)时,GIL将会被锁定,直到函数结束为止。
(2)退出线程
调用thread.exit()或sys.exit()或抛出一个SystemExit异常等。不过,不可以直接”杀掉“一个线程。
(3)在Python中使用线程
Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。
thread和threading用于创建和管理线程。
thread模块提供了基本的线程和锁的支持,而threading模块提供更高级别,功能更强的线程管理功能。threading模块的同步原语更丰富。
不建议使用thread模块:thread功能没有threading完善;thread对线程结束工作没有进行适当的控制。
4、thread模块
thread模块除了产生线程外,也提供了基本的同步数据结构锁对象(lock object,也叫原语锁、简单锁、互斥锁、互斥量、二值信号量)。
(1)模块函数
(2)LockType类型锁对象方法
5、threading模块
threading模块提供了Thread类,还提供了各种很好用的同步机制。
(1)threading模块对象
(2)Thread类
Thread类可以用多种方法来创建线程。
Thread类有很多thread模块里没有的函数。
(3)threading模块中的其他函数
(4)补充
守护线程:若设置一个线程为守护线程,在进程退出时,不用等待这个线程退出。整个Python会在所有的非守护线程退出后才结束。threading模块支持守护线程,thread模块不支持。
6、Queue模块
Queue模块可以用来进行线程间的通讯,让各个线程之间共享数据。
(1)Queue模块函数
(2)Queue对象函数
7 、相关模块