"Published" python 中跨进程可访问的值
"Published" value accessible across processes in python
我正在 python (3.7) 中编写软件,它涉及一个主 GUI 线程和多个子进程,每个子进程都作为状态机运行。
我希望子进程发布它们当前的状态机状态名称,以便主 GUI 线程可以检查状态机所处的状态。
我想找到一种方法来做到这一点,如果主进程和子进程同时尝试 read/write 到状态变量,主进程会立即(没有 locking/waiting) 得到一个稍微过时的状态,子进程会立即(没有locking/waiting)将当前状态写入状态变量。
基本上,我想确保子进程不会因为同时访问状态变量而得到任何 latency/jitter,而且我不关心 GUI 是否得到稍微过时的值。
我调查了:
- 使用
queue.Queue
,maxsize
为 1
,但 the behavior
queue.Queue
是在队列用完 space 时阻塞 - 它会
如果 behaved like a collections.deque
和
如果有新的值进来,默默地让最旧的值走在木板上
没有可用的 space.
- 使用
multiprocessing.Value
,但来自
the documentation,听起来你需要获取一个锁才能
访问或写入值,这就是我想要避免的 - 不
locking/blocking 同时 read/write 秒。它说了些什么
含糊不清如果你不使用锁,它就不会 'process-safe',
但我真的不知道那是什么意思——什么坏事会
完全没有使用锁就发生了?
完成此任务的最佳方法是什么?谢谢!
出于某种原因,我忘记了可以 put
以非阻塞方式进入队列!
我找到的解决方案是使用 multiprocessing.Queue
和 maxsize=1
,并在生产者(子进程)端使用非阻塞写入。这是我所做的简短版本:
正在父进程中初始化:
import multiprocessing as mp
import queue
publishedValue = mp.Queue(maxsize=1)
在重复调度的 GUI 函数中("consumer"):
try:
# Attempt to get an updated published value
publishedValue.get(block=False)
except queue.Empty:
# No new published value available
pass
在子 "producer" 进程中:
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
对象而不是队列来实现,但文档没有做到这一点显而易见(对我来说)如何做到这一点。
希望这对某人有所帮助。
我正在 python (3.7) 中编写软件,它涉及一个主 GUI 线程和多个子进程,每个子进程都作为状态机运行。
我希望子进程发布它们当前的状态机状态名称,以便主 GUI 线程可以检查状态机所处的状态。
我想找到一种方法来做到这一点,如果主进程和子进程同时尝试 read/write 到状态变量,主进程会立即(没有 locking/waiting) 得到一个稍微过时的状态,子进程会立即(没有locking/waiting)将当前状态写入状态变量。
基本上,我想确保子进程不会因为同时访问状态变量而得到任何 latency/jitter,而且我不关心 GUI 是否得到稍微过时的值。
我调查了:
- 使用
queue.Queue
,maxsize
为1
,但 the behaviorqueue.Queue
是在队列用完 space 时阻塞 - 它会 如果 behaved like acollections.deque
和 如果有新的值进来,默默地让最旧的值走在木板上 没有可用的 space. - 使用
multiprocessing.Value
,但来自 the documentation,听起来你需要获取一个锁才能 访问或写入值,这就是我想要避免的 - 不 locking/blocking 同时 read/write 秒。它说了些什么 含糊不清如果你不使用锁,它就不会 'process-safe', 但我真的不知道那是什么意思——什么坏事会 完全没有使用锁就发生了?
完成此任务的最佳方法是什么?谢谢!
出于某种原因,我忘记了可以 put
以非阻塞方式进入队列!
我找到的解决方案是使用 multiprocessing.Queue
和 maxsize=1
,并在生产者(子进程)端使用非阻塞写入。这是我所做的简短版本:
正在父进程中初始化:
import multiprocessing as mp
import queue
publishedValue = mp.Queue(maxsize=1)
在重复调度的 GUI 函数中("consumer"):
try:
# Attempt to get an updated published value
publishedValue.get(block=False)
except queue.Empty:
# No new published value available
pass
在子 "producer" 进程中:
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
对象而不是队列来实现,但文档没有做到这一点显而易见(对我来说)如何做到这一点。
希望这对某人有所帮助。