Python的多线程模块包括 _thread(thread)、threading、 queue,在 python3 里主要使用的是 threading。

threading 模块

函数

函数 作用
active_count() 返回当前活动的线程对象数量
current_thread() 返回当前线程对象
get_ident() 返回当前线程的 ID ,这是一个非零整数
enumerate() 枚举函数,返回当前活动的所有线程对象(以列表形式)
main _thread() 返回主线程对象,在正常情况下,主线程是 Python 解释器启动的线程
settrace(func) 为从线程模块启动的所有线程设置跟踪功能,func 参数为自定义函数名
setprofile(func) 为从线程模块启动所有线程设置配置文件,func 参数为自定义函数名
srack_size([size]) 返回创建新线程时使用的线程堆栈大小,size 可选参数可以设置0~32768)范围的数值,默认值为0

常量

threading 提供了TIMEOUT_MAX 常量。

Lock.acquire()、RLock.acquire()、Condition.wait() 等方法超过这个常量限定的最大时间后,将抛出 OverflowError 异常错误信息。

threading 模块提供了 Thread、Lock、RLock、Condition、Semaphore、Event 等类

Thread类

Thread 类 通过调用用户指定函数 func,用于独立生成一个活动的线程。掉用用户指定函数 func,可以有两种方法:一是以参数形式传递给构造函数;二是通过继承 Thread 类,并重写 run() 方法,调用 func 函数。在 Thread 的子类中,只允许对 __init__() 和 run() 方法进行重写。

Thread 类以构造函数调用形式如下:

Thread(group = None,target = None,name = None,args=(),kwargs={},*,daemon=None)

​ group参数:用于保留,作为将来的扩展功能。可以忽略该参数,或设置 group = None

​ target参数:设置线程需要执行的自定义函数 func,如 target = func, 设置完成后,被 run() 方法调用;target=None 时,线程不执行任何操作。

​ name参数:指定需要执行的线程名称。不指定时,该类自动生成一个 Thread-N 形式的线程名称。

​ args参数:当自定义函数 func 带有参数时,把参数以元组形式通过 args 传递给 func。

​ kwargs参数:当自定义函数 func 带有参数时,把参数以字典形式通过 kwargs 传递给 func。

​ daemon参数:当 daemon 不是 None 时,通过设置(True 或 False) 确定是否守护进程;当 daemon =None 时,守护进程属性将会继承父进程的状态(主线程默认情况下都为非守护进程)。

Thread 类的主要方法

方法 作用
start() 线程启动状态(一个线程对象只能调用该方法一次),该方法必须在run()方法之前调用
run() 运行线程,使线程处于活动状态:在 run() 方法里执行指定的用户自定义函数 func。 该方法可以在 Thread 子类里被重新
join(timeout=None) 阻塞调用线程。等待调用该方法的线程对象运行,一直到该线程执行终止,阻塞才释放。timeout 为可选参数,可以设置阻塞时间(以秒为单位);当 timeout 参数不存在或为 None 时,该操作阻塞,知道线程终止。该方法运行在 run() 方法后
name 线程名称,初始名称由构造函数设置
ident x线程的 ID 号,如果线程尚未启动,则为 None;线程启动后时一个非零整数
is_alive 返回线程是否存在
daemon x显示此线程是否为守护进进程(True)或不(False) 的布尔值。这必须在调用 start() 之前设置,否则会引发 RuntimeError。他的初始值是从创建线程继承的。主线程不是守护进程线程,因此在主线程中创建的所有线程都默认为守护程序= false

​ 一旦一个线程对象被创建,其活动必须通过调用线程的 start() 方法来启动;然后调用 run() 方法执行指定的用户自定义函数 func。 join() 方法在 run() 方法后执行。这会阻塞调用线程,直到调用 join() 方法的线程运行终止,才能执行后续程序代码。

Lock 类

Lock 类对象是原始锁,提供低级别的同步原语,由 _thread 扩展模块直接实现,一旦一个线程获得了一个锁,随后获取他的尝试将被阻塞,直到它被释放;任何线程都可能释放它。原始锁有‘锁定’ ‘解锁’ 两种状态,对应两个基本操作方法 acquire() 和 release()。

​ acquire() 建立一个锁,建立成功返回一个True值,建立失败返回一个False

​ release() 释放一个锁

RLock类

RLock 类对象为可重复锁,它可以被同一个线程多次获取,可以避免 Lock 多次锁定产生的死锁问题。acquire() 和 release() 同样提供 “锁定” “解锁” 功能,与 Lock 的区别:可以嵌套调用锁定和解锁方法

Condition类

Condition(条件变量) 对象提供了对复杂线程同步问题的支持功能。其除了提供与 Lock 类相同的 acuqire() 和 release() 方法外,还提供了wait() 和 notify()方法

Semaphore类

Semaphore (信号量)是荷兰早期计算机科学家 Edsger W.Dijkstra (他用名字 P() 和 V() 代替 acquire() 和 release()) 发明的计算机科学史上最古老的同步原语之一。一个信号量管理一个内部计数器,该计算器由每个 acquire() 调用递减,并由每个release() 调用递增。

queue模块

queue 模块实现多生产者、多消费者队列。当信息必须在多个线程之间安全的交换时,它在线程编程中特别有用。此模块中的Queue 类实现了所有必须的锁机制。该技术时多线程之间安全共享数据的最佳选择技术之一。