Skip to content

线程

线程是具有独立指令集的最小执行单元。它是进程的一部分,并在共享程序的可运行资源(如内存)的相同上下文中运行。一个线程有一个起点、一个执行顺序和一个结果。它有一个指令指针,用于保存线程的当前状态并控制接下来按什么顺序执行。

由于 GIL 锁的限制,除了网络 IO 功能,基本不推荐使用自己使用线程。

threading模块是 python3 推荐使用的内置模块。

multiprocessing的使用基本一致

新建线程

multiprocessing.Process基本一样

python
# _*_coding:utf-8_*_
from threading import Thread


def f(food):
    print("我单推", food)


if __name__ == "__main__":
    p = Thread(target=f, args=("ayame",))
    p.start()
    print("摸了")

线程对象方法

  • .start() 启动
  • .join(timeout = None) 阻塞主程序直到超时或线程允许完毕了

使用threading.Lock

  • lock.acquire() 关锁
  • lock.release() 解锁

锁可以被用作 with 语句的上下文管理器

队列

使用queue模块

1、class queue.Queue(maxsize) FIFO 先进先出
2、class queue.LifoQueue(maxsize) LIFO 先进后出
3、class queue.PriorityQueue(maxsize) 优先级队列

线程利用队列对象的getput来通信。另有简易的queue.SimpleQueue

定时器

使用threading.Timer(timeout, target),每隔 timeout 执行一次 target 函数

  • timer.start() 启动
  • timer.cancel() 取消

线程池一般使用from concurrent.futures import ThreadPoolExecutor

进程池则一般不使用from concurrent.futures import ProcessPoolExecutor

因为concurrent.Future较为重

python
import threading, time
from concurrent.futures import ThreadPoolExecutor

pool = ThreadPoolExecutor(max_workers=8)
lock = threading.Lock()
var = 0


def f():
    global var
    with lock:
        if (var := var + 1) < 10:
            time.sleep(0.5)
            print(var)
        else:
            print("跳过")


for _ in range(100):
    pool.submit(f)

pool.shutdown(wait=True)
input("\r\n结束")

池的 max_workers 默认为 min(32, os.cpu_count() + 4)

即它最多会使用 32 个 CPU 核心,默认会保留至少 5 个工作线程用于 I/O 密集型任务。