多进程异常:仅启动首个进程,并行执行功能失效求助
解决多进程/多线程仅启动第一个任务的问题
嘿,我来帮你搞定这个并行运行的问题!你说不管用threading还是multiprocessing,都只有第一个进程/线程跑起来,剩下的没动静,大概率是启动方式或者代码结构踩了坑。我给你拆解下常见问题,再给你改好的示例代码。
常见的问题原因
- 误用
run()代替start():很多新手会犯这个错——run()是同步执行,会阻塞主程序,必须等当前任务跑完才会执行下一个;而start()才是真正启动新的线程/进程,异步并行执行。 - 主进程提前退出:如果主程序没等待子进程/线程完成,主进程一结束,所有子进程/线程会被直接杀死,看起来就像没启动过。
- Windows下multiprocessing缺少
if __name__ == "__main__"::Windows系统创建子进程时会重新导入主模块,没有这个判断的话,会导致子进程重复执行主程序逻辑,进而引发异常或无法正常启动。
修复后的代码示例
1. 使用threading实现并行
import threading import time import logging # 假设你的LOGGER和machine实例已经定义完成 LOGGER = logging.getLogger(__name__) class Machine: def collect_network_connections(self): print("[CDA] 正在收集网络连接信息") def send_machine(self): print("[CDA] 正在发送机器信息") machine = Machine() def cda(): while True: try: machine.collect_network_connections() machine.send_machine() time.sleep(10) except Exception as excp: LOGGER.critical(f"CDA出错: {str(excp)}") time.sleep(10) def cld(): while True: try: print("[CLD] 正在收集系统日志信息") # 这里替换成你的cld实际业务逻辑 time.sleep(15) except Exception as excp: LOGGER.critical(f"CLD出错: {str(excp)}") time.sleep(15) if __name__ == "__main__": # 创建线程对象 thread_cda = threading.Thread(target=cda) thread_cld = threading.Thread(target=cld) # 可选:设置为守护线程,主程序退出时自动结束线程 thread_cda.daemon = True thread_cld.daemon = True # 启动线程(关键!用start()而不是run()) thread_cda.start() thread_cld.start() # 让主程序保持运行,避免提前退出 try: while True: time.sleep(1) except KeyboardInterrupt: print("程序被用户手动中断")
2. 使用multiprocessing实现并行
import multiprocessing import time import logging LOGGER = logging.getLogger(__name__) class Machine: def collect_network_connections(self): print("[CDA] 正在收集网络连接信息") def send_machine(self): print("[CDA] 正在发送机器信息") machine = Machine() def cda(): while True: try: machine.collect_network_connections() machine.send_machine() time.sleep(10) except Exception as excp: LOGGER.critical(f"CDA出错: {str(excp)}") time.sleep(10) def cld(): while True: try: print("[CLD] 正在收集系统日志信息") # 这里替换成你的cld实际业务逻辑 time.sleep(15) except Exception as excp: LOGGER.critical(f"CLD出错: {str(excp)}") time.sleep(15) if __name__ == "__main__": # 创建进程对象 proc_cda = multiprocessing.Process(target=cda) proc_cld = multiprocessing.Process(target=cld) # 启动进程(关键!用start()而不是run()) proc_cda.start() proc_cld.start() # 等待进程结束(因为是无限循环,这里会一直阻塞主进程) proc_cda.join() proc_cld.join()
额外注意事项
- 资源共享:如果
cda和cld需要共享数据,线程可以用threading.Lock避免数据竞争;进程则需要用multiprocessing.Manager、Queue等进程间通信工具,不能直接用全局变量。 - 日志输出:多进程环境下,建议给日志加上进程ID标识,方便区分不同进程的输出;线程则可以加线程ID。
- 异常捕获:你的代码里已经加了异常捕获,但可以补充具体的错误信息,方便排查问题。
内容的提问来源于stack exchange,提问作者Brain Monkey
相关产品推荐
相关产品推荐

