from threading import Thread 是 Python 中用于导入 Thread 类的语句。Thread 类属于 threading 模块,用于创建和管理线程。线程是程序执行的最小单元,允许程序在同一时间内执行多个任务。

常用用法

  1. 创建线程
    通过继承 Thread 类并重写 run() 方法来定义线程的执行逻辑。

    from threading import Thread
    
    class MyThread(Thread):
        def run(self):
            print("线程正在运行")
    
    # 创建线程实例
    t = MyThread()
    # 启动线程
    t.start()
    # 等待线程结束
    t.join()
  2. 直接使用 Thread
    可以通过传递一个可调用对象(如函数)给 Thread 的构造函数来创建线程。

    from threading import Thread
    
    def worker():
        print("线程正在运行")
    
    # 创建线程实例
    t = Thread(target=worker)
    # 启动线程
    t.start()
    # 等待线程结束
    t.join()
  3. 传递参数给线程
    可以使用 argskwargs 参数将参数传递给线程函数。

    from threading import Thread
    
    def worker(name, count):
        for i in range(count):
            print(f"{name}: {i}")
    
    # 创建线程实例并传递参数
    t = Thread(target=worker, args=("线程1", 5))
    # 启动线程
    t.start()
    # 等待线程结束
    t.join()
  4. 守护线程
    通过设置 daemon 属性为 True,可以将线程设置为守护线程。守护线程会在主线程结束时自动退出。

    from threading import Thread
    import time
    
    def worker():
        while True:
            print("守护线程正在运行")
            time.sleep(1)
    
    # 创建线程实例并设置为守护线程
    t = Thread(target=worker, daemon=True)
    # 启动线程
    t.start()
    # 主线程等待一段时间
    time.sleep(5)
    print("主线程结束")
  5. 线程同步
    使用 LockEventCondition 等同步原语来协调多个线程的执行。

    from threading import Thread, Lock
    
    lock = Lock()
    shared_data = 0
    
    def worker():
        global shared_data
        with lock:
            shared_data += 1
            print(f"共享数据: {shared_data}")
    
    threads = []
    for i in range(5):
        t = Thread(target=worker)
        threads.append(t)
        t.start()
    
    for t in threads:
        t.join()

总结

Thread 类提供了多线程编程的基础功能,适用于需要并发执行的场景。通过合理使用线程,可以提高程序的效率和响应性。


辨析:

Thread 类本身并不直接提供异步执行的能力,但它可以通过多线程的方式实现并发执行,从而模拟异步行为。Python 中的异步编程通常使用 asyncio 模块,而 Thread 类更适合用于 I/O 密集型任务或需要并行执行的场景。

以下是一个使用 Thread 类模拟异步执行的例子:


示例:使用 Thread 实现并发任务

from threading import Thread
import time

# 定义一个耗时任务
def task(name, delay):
    print(f"任务 {name} 开始执行")
    time.sleep(delay)  # 模拟耗时操作
    print(f"任务 {name} 完成")

# 创建多个线程来并发执行任务
threads = []
for i in range(3):
    t = Thread(target=task, args=(f"任务-{i+1}", 2))  # 每个任务耗时 2 秒
    threads.append(t)
    t.start()  # 启动线程

# 等待所有线程完成
for t in threads:
    t.join()

print("所有任务完成")

输出结果

任务 任务-1 开始执行
任务 任务-2 开始执行
任务 任务-3 开始执行
任务 任务-1 完成
任务 任务-2 完成
任务 任务-3 完成
所有任务完成

关键点

  1. 并发执行

    • 多个线程同时启动,任务会并发执行。
    • 在这个例子中,3 个任务几乎同时开始,并在 2 秒后几乎同时完成。
  2. 模拟异步

    • 虽然 Thread 不是真正的异步(异步通常指单线程下的非阻塞操作),但它可以通过多线程实现类似的效果。
  3. 适用场景

    • 适合 I/O 密集型任务(如文件读写、网络请求)。
    • 不适合 CPU 密集型任务(因为 Python 的 GIL 会限制多线程的并行性能)。

对比真正的异步编程(asyncio

如果你需要真正的异步编程(单线程非阻塞),可以使用 asyncio 模块。以下是一个简单的 asyncio 示例:

import asyncio

async def task(name, delay):
    print(f"任务 {name} 开始执行")
    await asyncio.sleep(delay)  # 非阻塞的 sleep
    print(f"任务 {name} 完成")

async def main():
    # 创建多个异步任务
    tasks = [
        asyncio.create_task(task("任务-1", 2)),
        asyncio.create_task(task("任务-2", 2)),
        asyncio.create_task(task("任务-3", 2)),
    ]
    await asyncio.gather(*tasks)  # 等待所有任务完成

# 运行异步任务
asyncio.run(main())

总结


为什么说 Threading 适合 I/O 密集型任务,而不适合 CPU 密集型任务?

1. 适合 I/O 密集型任务

2. 不适合 CPU 密集型任务


threading 库的底层实现

1. 底层实现

2. GIL 的作用

3. 绕过 GIL 的方法


总结