1. Python 多线程#

import threading
import time

def worker():
    """线程函数"""
    print("Worker thread started")
    time.sleep(5)
    print("Worker thread finished")

# 创建线程
t = threading.Thread(target=worker)

# 启动线程
t.start()

# 等待线程结束
t.join()

# 输出当前活动线程的数量
print("Active threads:", threading.active_count())

# 输出当前活动的线程列表
print("Active threads:", threading.enumerate())

# 输出当前线程的对象
print("Current thread:", threading.current_thread())

# 输出主线程的对象
print("Main thread:", threading.main_thread())
Worker thread started
Worker thread finished
Active threads: 6
Active threads: [<_MainThread(MainThread, started 12180)>, <Thread(IOPub, started daemon 13648)>, <Heartbeat(Heartbeat, started daemon 14888)>, <ControlThread(Control, started daemon 14924)>, <HistorySavingThread(IPythonHistorySavingThread, started 13100)>, <ParentPollerWindows(Thread-4, started daemon 13096)>]
Current thread: <_MainThread(MainThread, started 12180)>
Main thread: <_MainThread(MainThread, started 12180)>

1.1. 线程对象#

创建一个线程对象用以下两种方法:

  1. 向构造器传递一个可调用对象

  2. 在子类中重载run()方法

当线程对象一旦被创建,其活动必须通过调用线程的 start() 方法开始。 这会在独立的控制线程中发起调用 run() 方法。

其他线程可以调用一个线程的 join() 方法。这会阻塞调用该方法的线程,直到被调用 join() 方法的线程终结。

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

一个线程可以被标记成一个“守护线程”。 这个标识的意义是,当剩下的线程都是守护线程时,整个 Python 程序将会退出。 初始值继承于创建线程。 这个标识可以通过 daemon 特征属性或者 daemon 构造器参数来设置。

备注

守护线程在程序关闭时会突然关闭。他们的资源(例如已经打开的文档,数据库事务等等)可能没有被正确释放。如果你想你的 线程正常停止,设置他们成为非守护模式并且使用合适的信号机制,例如: Event。

1.2. 锁对象#

原始锁处于 “锁定” 或者 “非锁定” 两种状态之一。它被创建时为非锁定状态。它有两个基本方法, acquire() 和 release() 。当状态为非锁定时, acquire() 将状态改为 锁定 并立即返回。当状态是锁定时, acquire() 将阻塞至其他线程调用 release() 将其改为非锁定状态,然后 acquire() 调用重置其为锁定状态并返回。 release() 只在锁定状态下调用; 它将状态改为非锁定并立即返回。如果尝试释放一个非锁定的锁,则会引发 RuntimeError 异常。

锁同样支持 上下文管理协议。

当多个线程在 acquire() 等待状态转变为未锁定被阻塞,然后 release() 重置状态为未锁定时,只有一个线程能继续执行;至于哪个等待线程继续执行没有定义,并且会根据实现而不同。

1.3. 递归锁对象#

重入锁是一个可以被同一个线程多次获取的同步基元组件。在内部,它在基元锁的锁定/非锁定状态上附加了 “所属线程” 和 “递归等级” 的概念。在锁定状态下,某些线程拥有锁 ; 在非锁定状态下, 没有线程拥有它。

若要锁定锁,线程调用其 acquire() 方法;一旦线程拥有了锁,方法将返回。若要解锁,线程调用 release() 方法。 acquire()/release() 对可以嵌套;只有最终 release() (最外面一对的 release() ) 将锁解开,才能让其他线程继续处理 acquire() 阻塞。

递归锁也支持 上下文管理协议。

1.4. 条件对象#

1.5. 信号量对象#

1.6. 事件对象#

1.7. 定时器对象#

1.8. 栅栏对象#

1.9. 在 with 语句中使用锁、条件和信号量#