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

Python multiprocessing:启动进程后multiprocessing.Value恢复默认值问题

问题分析与解决方法

问题根源

  1. 普通实例变量丢失(如bind_port):
    在Windows系统的spawn进程启动模式下,子进程会重新导入模块并创建Process子类实例,父进程初始化时设置的普通实例变量不会被子进程继承;即使是Unix的fork模式,若后续修改父进程变量,子进程也无法同步。
  2. laser_password为空:
    使用multiprocessing.Value(c_wchar_p, ...)时,c_wchar_p是指向宽字符的指针,进程启动后指针指向的内存地址在子进程中无效,导致值变为空字符串。

解决步骤

1. 修复普通变量的进程共享

将需要跨进程保留的普通变量(如bind_port)改为multiprocessing.Value类型,确保值能在进程间共享:

# 替换原bind_port初始化代码
self.bind_port = multiprocessing.Value('i', int(kwargs["bind_port"]) if "bind_port" in kwargs else 0)
# 后续访问时使用.value属性
print(self.bind_port.value)

2. 修复字符串类型的进程共享

不要用指针类型存储字符串,改用以下两种可靠方式:

方式一:使用multiprocessing.Manager().Value

from multiprocessing import Manager
manager = Manager()
# 替换原laser_password初始化代码
self.laser_password = manager.Value(str, kwargs.get("laser_password", self.DEFAULT_PASSWORD))
# 直接通过.value访问/修改
logger.info(f"Current password: {self.laser_password.value}")

方式二:使用multiprocessing.Array

适合固定长度的字符串:

password_str = kwargs.get("laser_password", self.DEFAULT_PASSWORD)
# 定义最大长度(示例为20),编码为字节
self.laser_password = multiprocessing.Array('c', password_str.encode('utf-8'), lock=True)
# 读取时解码
current_pwd = self.laser_password.value.decode('utf-8').rstrip('\x00')
# 修改时重新编码赋值
self.laser_password.value = "new_password".encode('utf-8')

3. 兼容Windows的spawn模式

确保启动代码放在if __name__ == '__main__':保护块内,避免子进程重复初始化模块:

if __name__ == '__main__':
    emulator = EmulatorViron(bind_port=30800, laser_password="helloworld")
    emulator.start()
    emulator.join()

4. 完整修改后的核心代码片段

class EmulatorViron(multiprocessing.Process):
    BIND_PORT_RANGE = [30800, 30900]
    socket = None
    DEFAULT_PASSWORD = ""

    COOLING_TEMP_MIN = 15.0
    COOLING_TEMP_MAX = 90.0

    HEATING_COEF = 2.5  # roughly degrees / sec
    COOLING_COEF = 2.0  # roughly degrees / sec

    def __init__(self, **kwargs):
        super().__init__()
        logger.info(f"Received kwargs: {kwargs}")
        # 改用Value存储bind_port
        self.bind_port = multiprocessing.Value('i', int(kwargs["bind_port"]) if "bind_port" in kwargs else 0)
        self.socket = None
        # Initialize version
        self.device_identifier = kwargs.get("device_identifier", "VIRON")
        # 用Manager的Value存储密码
        from multiprocessing import Manager
        manager = Manager()
        self.laser_password = manager.Value(str, kwargs.get("laser_password", self.DEFAULT_PASSWORD))
        logger.info(f"Current password: {self.laser_password.value}")
        # 其他普通变量也改用Value确保共享
        self.operation_delay = multiprocessing.Value('f', kwargs.get("operation_delay", 1.0))
        self.delay_between_commands = multiprocessing.Value('f', kwargs.get("delay_between_commands", 0.1))

        # 原有状态变量保持不变
        self.user_authenticated = multiprocessing.Value(c_bool, kwargs.get("user_authenticated", False))
        self.fire_mode = multiprocessing.Value(c_bool, kwargs.get("fire_mode", False))
        self.standby_mode = multiprocessing.Value(c_bool, kwargs.get("standby_mode", False))
        self.is_flashing = multiprocessing.Value(c_bool, kwargs.get("is_flashing", False))
        self.is_switching = multiprocessing.Value(c_bool, kwargs.get("is_switching", False))
        self.user_shots = multiprocessing.Value("i", kwargs.get("user_shots", 8001))
        self.fl_mode_int = multiprocessing.Value(c_bool, kwargs.get("fl_mode", True))
        self.qs_mode_int = multiprocessing.Value(c_bool, kwargs.get("qs_mode", True))
        self.qs_delay = multiprocessing.Value("i", kwargs.get("qs_delay", 50))
        self.cooling_temp = multiprocessing.Value("f", kwargs.get("t_cool", self.COOLING_TEMP_MIN))

        self.bnc_interlock = multiprocessing.Value(c_bool, kwargs.get("bnc_interlock", False))

        self.client_port_name = ""
        self._initialize_connection()
        self._running_flag = multiprocessing.Event()

内容的提问来源于stack exchange,提问作者Firebug2309

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 02:20:56