Python如何实现多线程、多进程任务同时并行执行
问题根源
你的代码始终顺序执行,核心是两个错误:
- 给
Thread/Process传target参数时,直接写了countdown(参数1,参数2)——这行代码会在主线程立刻同步执行countdown函数,等函数执行完拿到返回值(此处为None)才会传给构造器,根本没有把函数交给子任务调度,自然会按调用顺序串行跑。正确的传参方式是:把函数名(不带后面的调用括号)传给target,函数需要的参数单独通过args参数(元组类型)传入。 - 第二版代码创建完
Process、Thread对象后,没有调用.start()方法,就算参数传对了,子任务也不会被启动。
线程与进程的基础差异
针对你提到的Windows下表现相关的疑问,两者核心区别如下:
- 进程是操作系统分配资源的独立单位,每个进程有独立的内存空间,开启多进程时Windows任务管理器会显示多个独立的python.exe进程,进程间数据默认不互通,切换开销大,适合运行CPU密集型任务(比如大规模数值计算、视频转码)。
- 线程是进程内部的执行单元,同一个进程下的所有线程共享进程的内存空间,开启多线程时任务管理器只会显示一个对应进程,线程切换开销小,适合IO密集型场景。你要实现的定时自动保存、监听键盘输入都属于IO密集型场景(大部分时间在等待计时到期、等待用户输入,不是满负荷做计算),用多线程就足够,不需要开多进程。
修正后的可运行代码
并行倒计时测试代码(线程版)
import time import threading def countdown(length, delay): length += 1 while length > 0: time.sleep(delay) length -= 1 # 加flush=True避免打印缓冲导致输出不及时、顺序错乱 print(length, end=" ", flush=True) if __name__ == "__main__": # 注意:target传函数名不带括号,参数通过args元组传入,创建完对象必须调用start() t1 = threading.Thread(target=countdown, args=(3, 2)) t2 = threading.Thread(target=countdown, args=(3, 1)) t1.start() t2.start() # 等待子线程执行完毕再退出主线程 t1.join() t2.join()
运行后可以看到两个倒计时完全并行:1秒间隔的倒计时会依次输出2、1、0,2秒间隔的倒计时会同步输出对应数字,不会等第一个任务跑完才启动第二个。
自动保存+键盘输入线程参考实现
import time import threading # 自动保存间隔,单位秒,正式使用时替换为X分钟对应的秒数即可 AUTO_SAVE_INTERVAL = 60 stop_flag = False def auto_save_task(): while not stop_flag: time.sleep(AUTO_SAVE_INTERVAL) if stop_flag: break # 替换为实际的游戏存档写入逻辑 print("\n[系统] 自动保存完成", flush=True) def keyboard_input_task(): global stop_flag while not stop_flag: # 替换为实际的键盘输入监听、指令处理逻辑 cmd = input("\n请输入指令(输入exit退出程序):") if cmd == "exit": stop_flag = True print("[系统] 收到退出指令,准备关闭程序", flush=True) else: print(f"[系统] 已处理指令:{cmd}", flush=True) if __name__ == "__main__": # 自动保存线程设为守护线程,主线程退出时自动跟着结束,不会卡住进程 save_thread = threading.Thread(target=auto_save_task, daemon=True) input_thread = threading.Thread(target=keyboard_input_task) save_thread.start() input_thread.start() input_thread.join()
几个注意点:
- 多线程场景下打印内容建议加
flush=True,否则Python的输出缓冲可能导致打印内容不实时、挤在一起,看起来像任务还是串行的。 - Windows下写多进程代码必须把启动逻辑放在
if __name__ == "__main__":代码块中,否则会出现反复启动子进程的报错,多线程虽然没有这个强制要求,但保留这个写法可以避免很多跨平台兼容问题。
内容的提问来源于stack exchange,提问作者vahnx
相关产品推荐
相关产品推荐

