哎哟,昨天肝了一天Python写了个压测小脚本,就是多线程狂轰服务器那种~
结果发现!按Ctrl+C根本停不下来!!急得我直挠头
本来想着加个signal捕获SIGINT,改个全局flag让线程自己check退出,美滋滋~
结果一试——Ctrl+C按烂了,程序纹丝不动,还在那儿吭哧吭哧跑…(气抖冷)
搜了一圈才懂:Python里非守护线程(non-daemon thread)会把主线程拽住,信号根本进不来!
你设成daemon吧?更坑——主线程一收工,所有子线程直接被掐断,脚本闪退,日志都来不及打
最后整明白了:得双管齐下!
? 子线程设成 daemon(不然卡死)
? 主线程不能躺平,得主动等所有子线程跑完再退(不然全被强杀)
? signal照加,flag照改,但退出逻辑得兜住!
附上修好的精简版(已去注释&乱码,能直接跑):
python
!/usr/bin/env python
-*- coding: utf-8 -*-
import threading, signal, time
is_exit = False
def doStress(i, cc):
global is_exit
idx = i
while not is_exit:
if idx < 10000000:
print(fthread {i}: idx={idx})
idx += cc
else:
break
print(fthread {i} done.)
def handler(signum, frame):
global is_exit
is_exit = True
print(f\n?? 收到信号 {signum},准备优雅退出...)
if __name__ == __main__:
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
threads =
for i in range(cc):
t = threading.Thread(target=doStress, args=(i, cc))
t.setDaemon(True) 关键!不加这句Ctrl+C无效
t.start()
threads.append(t)
主线程不退出,等着所有子线程自然结束
for t in threads:
t.join() 这句不能少!否则主线程秒退,子线程被屠
print(? 全部线程已退出,压测结束!)
总结一句话:
想Ctrl+C停压测?daemon + join + signal 缺一不可!
(别问,问就是踩过坑的过来人)