首页 > 解决方案 > python中跨进程访问的“已发布”值

问题描述

我正在用 python (3.7) 编写软件,它涉及一个主 GUI 线程和多个子进程,每个子进程都作为状态机运行。

我希望子进程发布它们当前的状态机状态名称,以便主 GUI 线程可以检查状态机处于什么状态。

我想找到一种方法来做到这一点,如果主进程和子进程同时尝试读/写状态变量,主进程会立即(没有锁定/等待)稍微退出-of-date 状态,并且子进程将立即(没有锁定/等待)将当前状态写入状态变量。

基本上,我想确保子进程不会因为同时访问状态变量而获得任何延迟/抖动,并且我不在乎 GUI 是否获得稍微过时的值。

我调查了:

实现这一目标的最佳方法是什么?谢谢!

标签: pythonprocessmultiprocessinglocking

解决方案


由于某种原因,我忘记了可以以put非阻塞方式进入队列!

我找到的解决方案是使用multiprocessing.Queuewith maxsize=1,并在生产者(子进程)端使用非阻塞写入。这是我所做的简短版本:

在父进程中初始化:

import multiprocessing as mp
import queue

publishedValue = mp.Queue(maxsize=1)

在重复计划的 GUI 功能(“消费者”)中:

try:
    # Attempt to get an updated published value
    publishedValue.get(block=False)
except queue.Empty:
    # No new published value available
    pass

在子“生产者”过程中:

try:
    # Clear current value in case GUI hasn't already consumed it
    publishedValue.get(block=False)
except queue.Empty:
    # Published value has already been consumed, no problem
    pass

try:
    # Publish new value
    publishedValue.put(block=False)
except queue.Full:
    # Can't publish value right now, resource is locked
    pass

请注意,这确实要求子进程在被阻塞时可以反复尝试重新发布该值,否则消费者可能会完全错过发布的值(而不是简单地获得它有点晚)。

我认为这可能以更简洁的方式(并且可能具有更少的开销)通过对对象而不是队列的非阻塞写入来实现multiprocessing.Value,但是文档并没有明确(对我而言)如何做到这一点。

希望这可以帮助某人。


推荐阅读