Python使用threading/Process运行sleep计时程序无法并行问题求助
问题根源
你的并行逻辑失效是两个低级写法错误导致的,和用线程还是进程没有关系:
- 线程传参写法完全错误:你写的
Thread(target=timer(wait, stri)),本质是在主线程直接同步调用了timer函数,会先完整跑完整个倒计时、打印完提醒内容,才会把timer的返回值(None)赋值给target参数,之后才启动子线程。等于子线程根本没执行计时逻辑,所有等待全堵在主线程,当然不会先跑后续代码。 - 多进程版本误用join方法:
t1.join()的作用就是强制主线程阻塞,等当前子进程执行完毕后才会继续往下走,加了这行代码不管你用进程还是线程,都会卡在计时结束才执行后续逻辑。
另外原代码的时间换算逻辑有bug,输入带小时的时间格式时会算错总秒数。
修正后可直接运行的代码
from time import sleep from threading import Thread import threading # 打印锁,避免多线程同时输出导致内容错乱 print_lock = threading.Lock() def timer(seconds, remind_str): for _ in range(seconds): sleep(1) # 加锁保证提醒内容完整打印,不会和主线程输出混在一起 with print_lock: print(f"\n=== 提醒:{remind_str} ===") def timestart(): total_wait = 0 time_input = list(map(int, input("设置倒计时(支持格式:秒 / 分:秒 / 时:分:秒):").split(':'))) time_reversed = time_input[::-1] # 修正时间换算逻辑,按位对应秒、分、时,分别乘60的对应次幂 for i in range(len(time_reversed)): total_wait += (60 ** i) * time_reversed[i] remind_content = input("设置提醒内容:") # 正确传参:target传函数对象本身,参数通过args元组传入,不要直接调用函数 t1 = Thread(target=timer, args=(total_wait, remind_content), daemon=True) t1.start() if __name__ == "__main__": tip_map = { "Who": "Hello What is your name", "Good": "Its good to meet you", "Start": "Its time to start" } timestart() # 启动倒计时后会立刻执行后续代码,不需要等计时结束 name = tip_map["Who"] print(tip_map["Good"] + name) print(tip_map["Start"]) # 这里可以替换成你自己的任意业务逻辑,示例为持续接收用户输入 while True: content = input(">>> ") print(f"已收到输入:{content}")
关键修改点说明
- 线程/进程初始化时,
target参数只传函数名(函数对象),所有执行参数通过args以元组形式传入,不会在主线程提前执行计时逻辑 - 去掉了多进程版本里的
t1.join()调用,主线程启动计时任务后会立刻往下执行,不会阻塞等待 - 将子线程设置为
daemon=True守护线程,主线程退出时子线程会自动销毁,不会出现程序无法正常退出的问题 - 增加打印锁,避免倒计时提醒和主线程的打印同时执行导致内容错乱、串行
- 修正了时间换算逻辑,支持纯秒、分:秒、时:分:秒三种输入格式,比如输入
30代表30秒、1:30代表1分30秒、0:1:30同样代表1分30秒 - 如果偏好使用多进程实现,只需要把
Thread替换为Process,保持传参方式、去掉join、设置daemon=True即可,但倒计时属于IO密集型任务,线程开销远小于进程,更适合这个场景
运行后效果和手机提醒完全一致:设置完倒计时和提醒内容后,程序会立刻执行后续逻辑、正常接收输入输出,倒计时结束时会自动弹出提醒,不会阻塞任何操作。
内容的提问来源于stack exchange,提问作者Tony Stark 001
相关产品推荐
相关产品推荐

