You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程异常:仅启动首个进程,并行执行功能失效求助

解决多进程/多线程仅启动第一个任务的问题

嘿,我来帮你搞定这个并行运行的问题!你说不管用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:22:36