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

Python多进程中DMXValues变量跨进程共享异常问题求助

问题描述

我编写了一个使用multiprocessing和sacn库的Python脚本:

from multiprocessing import Process
import time 
import sacn 

def GettingDMXValues():
    while True:

        receiver = sacn.sACNreceiver(bind_address = "***.**.**.**")
        receiver.start()  

        @receiver.listen_on('universe', universe=1) 
        def callback(packet):  
            #print(packet.dmxData) 
            global DMXValues
            DMXValues = packet.dmxData
            print(DMXValues)
                  
        receiver.join_multicast(1)

        time.sleep(10)  

        receiver.leave_multicast(1)

        receiver.stop()

def printtest2():
    while True:
        print(DMXValues)


p1 = Process(target=GettingDMXValues)
p2 = Process(target=printtest2)

if __name__ == '__main__':
    p1.start()
    time.sleep(1)
    p2.start()

第一个函数能正常运行并打印DMX数据,但第二个函数尝试打印DMXValues时提示变量未定义;如果在脚本开头定义该变量,第二个进程只会打印初始值,不会同步第一个进程的更新结果。


问题核心

Python的multiprocessing创建的进程拥有完全独立的内存空间,进程间的全局变量是隔离的。你在第一个进程里用global声明的DMXValues只存在于该进程的内存中,第二个进程根本无法访问;如果在主进程定义初始值,子进程启动时会复制一份到自己的内存,后续第一个进程的修改不会同步到第二个进程。


解决方法

要实现多进程间的数据共享,必须使用multiprocessing提供的同步机制,以下是两种常用方案:

方案1:使用Queue(队列,适合生产者-消费者模式)

队列是进程安全的,可单向传递数据,适合持续更新的场景:

from multiprocessing import Process, Queue
import time 
import sacn 

def GettingDMXValues(dmx_queue):
    while True:
        receiver = sacn.sACNreceiver(bind_address = "***.**.**.**")
        receiver.start()  

        @receiver.listen_on('universe', universe=1) 
        def callback(packet):  
            dmx_data = packet.dmxData
            print(dmx_data)
            # 清空队列旧数据,只保留最新值
            if not dmx_queue.empty():
                try:
                    dmx_queue.get_nowait()
                except:
                    pass
            dmx_queue.put(dmx_data)
                  
        receiver.join_multicast(1)
        time.sleep(10)  
        receiver.leave_multicast(1)
        receiver.stop()

def printtest2(dmx_queue):
    last_data = []
    while True:
        try:
            # 获取最新DMX数据
            last_data = dmx_queue.get_nowait()
            print(last_data)
        except:
            # 队列空时打印上次保存的值
            if last_data:
                print(last_data)
        time.sleep(0.1)  # 避免过度占用CPU

if __name__ == '__main__':
    dmx_queue = Queue()
    p1 = Process(target=GettingDMXValues, args=(dmx_queue,))
    p2 = Process(target=printtest2, args=(dmx_queue,))
    p1.start()
    time.sleep(1)
    p2.start()

方案2:使用Manager的共享容器

如果需要更灵活的共享操作,可以用Manager创建跨进程访问的列表/字典:

from multiprocessing import Process, Manager
import time 
import sacn 

def GettingDMXValues(dmx_list):
    while True:
        receiver = sacn.sACNreceiver(bind_address = "***.**.**.**")
        receiver.start()  

        @receiver.listen_on('universe', universe=1) 
        def callback(packet):  
            dmx_data = packet.dmxData
            print(dmx_data)
            # 更新共享列表内容
            dmx_list.clear()
            dmx_list.extend(dmx_data)
                  
        receiver.join_multicast(1)
        time.sleep(10)  
        receiver.leave_multicast(1)
        receiver.stop()

def printtest2(dmx_list):
    while True:
        if dmx_list:
            print(dmx_list)
        time.sleep(0.1)

if __name__ == '__main__':
    with Manager() as manager:
        dmx_list = manager.list()
        p1 = Process(target=GettingDMXValues, args=(dmx_list,))
        p2 = Process(target=printtest2, args=(dmx_list,))
        p1.start()
        time.sleep(1)
        p2.start()
        p1.join()
        p2.join()

额外提示
  • 永远不要依赖全局变量实现多进程数据共享,这是多进程开发的常见误区
  • 回调函数内的操作尽量简洁,避免阻塞,防止影响sACN数据的接收效率
  • 根据实际场景选择同步方式:队列适合单向传递,Manager适合复杂的多进程共享操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:27:47