线程
线程是具有独立指令集的最小执行单元。它是进程的一部分,并在共享程序的可运行资源(如内存)的相同上下文中运行。一个线程有一个起点、一个执行顺序和一个结果。它有一个指令指针,用于保存线程的当前状态并控制接下来按什么顺序执行。
由于 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) 优先级队列
线程利用队列对象的get
和put
来通信。另有简易的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 密集型任务。