相关属性和方法
-
Thread对象的属性
属性 | 描述 |
---|---|
name | 线程名 |
ident | 线程的标识符 |
daemon | 布尔标志,表示这个线程是否是守护线程 |
-
Thread对象的方法
方法 | 描述 |
---|---|
init(group=None, tatget=None, name=None, args=(), kwargs ={}, verbose=None, daemon=None) | 实例化一个线程对象,需要有一个可调用的 target,以及其参数 args 或 kwargs。还可以传递 name 或 group 参数,不过后者还未实现。此 外 , verbose 标 志 也 是 可 接 受 的 。 而 daemon 的 值 将 会 设 定 thread.daemon 属性/标志 |
start() | 开始执行该线程 |
run() | 定义线程功能的方法(通常在子类中被应用开发者重写) |
join (timeout=None) | 直至启动的线程终止之前一直挂起;除非给出了 timeout(秒),否则 会一直阻塞 |
is_alive() | 布尔标志,表示这个线程是否还存活 |
-
threading模块其他函数
函数 | 描述 |
---|---|
start() | 开始执行该线程 |
active_count() | 当前活动的 Thread 对象个数 |
enumerate() | 返回当前活动的 Thread 对象列表 |
settrace(func) | 为所有线程设置一个 trace 函数 |
setprofile (func) | 为所有线程设置一个 profile 函数 |
stack_size(size=0) | 返回新创建线程的栈大小;或为后续创建的线程设定栈的大小 为 size |
Lock() | 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取,对象有acquire()和release()方法 |
RLock() | 多重锁,在同一线程中可用被多次acquire。如果使用RLock,那么acquire和release必须成对出现,调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象 |
后记
在Python多线程下,每个线程的执行方式:
1、获取GIL
2、执行代码直到sleep或者是python虚拟机将其挂起。
3、释放GIL
通常来说,多线程是一个好东西。不过由于 Python 的 GIL 的限制,多线程更适合于 I/O 密集型应用(I/O 释放了 GIL,可以允 许更多的并发),而不是计算密集型应用。对于后一种情况而言,为了实现更好的并行性,你需要使用多进程,以便让 CPU 的其他内核来执行。
请注意:多核多线程比单核多线程更差,原因是单核下多线程,每次释放GIL,唤醒的那个线程都能获取到GIL锁,所以能够无缝执行,但多核下,CPU0释放GIL后,其他CPU上的线程都会进行竞争,但GIL可能会马上又被CPU0拿到,导致其他几个CPU上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,这样会造成线程颠簸(thrashing),导致效率更低