• 我们在哪一颗星上见过 ,以至如此相互思念 ;我们在哪一颗星上相互思念过,以至如此相互深爱
  • 我们在哪一颗星上分别 ,以至如此相互辉映 ;我们在哪一颗星上入睡 ,以至如此唤醒黎明
  • 认识世界 克服困难 洞悉所有 贴近生活 寻找珍爱 感受彼此

python模块:threading-基于线程的并行

python知识点 云涯 4年前 (2020-12-14) 1829次浏览

概述

源代码: Lib/threading.py

参考文档https://docs.python.org/zh-cn/3.8/library/threading.html

在 CPython 中,由于存在 全局解释器锁,同一时刻只有一个线程可以执行 Python 代码(虽然某些性能导向的库可能会去除此限制)。 如果你想让你的应用更好地利用多核心计算机的计算资源,推荐你使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。 但是,如果你想要同时运行多个 I/O 密集型任务,则多线程仍然是一个合适的模型。

 

方法

threading.active_count()

返回当前存活的 Thread 对象的数量。 返回值与 enumerate() 所返回的列表长度一致。

threading.current_thread()

返回当前对应调用者的控制线程的 Thread 对象。

如果调用者的控制线程不是利用 threading 创建,会返回一个功能受限的虚拟线程对象。

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

group 应该为 None;为了日后扩展 ThreadGroup 类实现而保留。

target 是用于 run() 方法调用的可调用对象。默认是 None,表示不需要调用任何方法。

name 是线程名称。默认情况下,由 “Thread-N” 格式构成一个唯一的名称,其中 N 是小的十进制数。

args 是用于调用目标函数的参数元组。默认是 ()。

kwargs 是用于调用目标函数的关键字参数字典。默认是 {}。

 

线程对象

start():

线程开始。它在一个线程里最多只能被调用一次。如果同一个线程对象中调用这个方法的次数大于一次,会抛出 RuntimeError 。

run():

线程活动的方法。可以在子类型里重载这个方法。 标准的 run() 方法会对作为 target 参数传递给该对象构造器的可调用对象(如果存在)发起调用,并附带从 args 和 kwargs 参数分别获取的位置和关键字参数。

join(timeout=None):

等待,直到线程终结。这会阻塞调用这个方法的线程,直到被调用 join() 的线程终结 — 不管是正常终结还是抛出未处理异常 — 或者直到发生超时,超时选项是可选的。

当 timeout 参数存在而且不是 None 时,它应该是一个用于指定操作超时的以秒为单位的浮点数或者分数。因为 join() 总是返回 None ,所以你一定要在 join() 后调用 is_alive() 才能判断是否发生超时 — 如果线程仍然存活,则 join() 超时。

当 timeout 参数不存在或者是 None ,这个操作会阻塞直到线程终结。

一个线程可以被 join() 很多次。

如果尝试加入当前线程会导致死锁, join() 会引起 RuntimeError 异常。如果尝试 join() 一个尚未开始的线程,也会抛出相同的异常。

name

只用于识别的字符串。它没有语义。多个线程可以赋予相同的名称。 初始名称由构造函数设置。

getName() 

setName()

旧的 name 取值/设值 API;直接当做特征属性使用它。

ident

这个线程的 ‘线程标识符’,如果线程尚未开始则为 None 。这是个非零整数。参见 get_ident() 函数。当一个线程退出而另外一个线程被创建,线程标识符会被复用。即使线程退出后,仍可得到标识符。

native_id

此线程的原生集成线程 ID。 这是一个非负整数,或者如果线程还未启动则为 None。 请参阅 get_native_id() 函数。 这表示线程 ID (TID) 已被 OS (内核) 赋值给线程。 它的值可能被用来在全系统范围内唯一地标识这个特定线程(直到线程终结,在那之后该值可能会被 OS 回收再利用)。

is_alive()

方法用于检查线程是否存活

如果 run() 方法引发了异常,则会调用 threading.excepthook() 来处理它。 在默认情况下,threading.excepthook() 会静默地忽略 SystemExit。

daemon

属性可以设定线程为“守护线程”。

一个表示这个线程是(True)否(False)守护线程的布尔值。一定要在调用 start() 前设置好,不然会抛出 RuntimeError 。初始值继承于创建线程;主线程不是守护线程,因此主线程创建的所有线程默认都是 daemon = False。

 

锁对象

原始锁是一个在锁定时不属于特定线程的同步基元组件。原始锁处于 “锁定” 或者 “非锁定” 两种状态之一。它被创建时为非锁定状态。

当状态为非锁定时, acquire() 将状态改为 锁定 并立即返回。

release() 只在锁定状态下调用; 它将状态改为非锁定并立即返回。如果尝试释放一个非锁定的锁,则会引发 RuntimeError  异常。

threading.Lock

实现原始锁对象的类。一旦一个线程获得一个锁,会阻塞随后尝试获得锁的线程,直到它被释放;任何线程都可以释放它。

acquire(blocking=True, timeout=-1)
可以阻塞或非阻塞地获得锁。

当调用时参数 blocking 设置为 True (缺省值),阻塞直到锁被释放,然后将锁锁定并返回 True 。

在参数 blocking 被设置为 False 的情况下调用,将不会发生阻塞。如果调用时 blocking 设为 True 会阻塞,并立即返回 False ;否则,将锁锁定并返回 True。

当浮点型 timeout 参数被设置为正值调用时,只要无法获得锁,将最多阻塞 timeout 设定的秒数。timeout 参数被设置为 -1 时将无限等待。当 blocking 为 false 时,timeout 指定的值将被忽略。

如果成功获得锁,则返回 True,否则返回 False (例如发生 超时 的时候)。

release()
释放一个锁。这个方法可以在任何线程中调用,不单指获得锁的线程。

当锁被锁定,将它重置为未锁定,并返回。如果其他线程正在等待这个锁解锁而被阻塞,只允许其中一个允许。

在未锁定的锁调用时,会引发 RuntimeError 异常。

没有返回值。

locked()
如果获得了锁则返回真值。

递归锁对象

重入锁是一个可以被同一个线程多次获取的同步基元组件。

在内部,它在基元锁的锁定/非锁定状态上附加了 “所属线程” 和 “递归等级” 的概念。在锁定状态下,某些线程拥有锁 ; 在非锁定状态下, 没有线程拥有它。

threading.RLock

此类实现了重入锁对象。重入锁必须由获取它的线程释放。一旦线程获得了重入锁,同一个线程再次获取它将不阻塞;线程必须在每次获取它时释放一次。

cquire(blocking=True, timeout=-1)、release()

未完待续……

 

 


云涯历险记 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python模块:threading-基于线程的并行
喜欢 (0)