python - python中跨进程访问的“已发布”值
问题描述
我正在用 python (3.7) 编写软件,它涉及一个主 GUI 线程和多个子进程,每个子进程都作为状态机运行。
我希望子进程发布它们当前的状态机状态名称,以便主 GUI 线程可以检查状态机处于什么状态。
我想找到一种方法来做到这一点,如果主进程和子进程同时尝试读/写状态变量,主进程会立即(没有锁定/等待)稍微退出-of-date 状态,并且子进程将立即(没有锁定/等待)将当前状态写入状态变量。
基本上,我想确保子进程不会因为同时访问状态变量而获得任何延迟/抖动,并且我不在乎 GUI 是否获得稍微过时的值。
我调查了:
- 使用 a
queue.Queue
和 a ,但如果队列空间不足,则maxsize
of的行为是 阻塞 - 如果它的行为类似于a并且如果新的值没有可用的情况下,它会默默地让最旧的值走在木板上,这将适用于我的目的空间。1
queue.Queue
collections.deque
- 使用 a
multiprocessing.Value
,但从 文档中,听起来您需要获取锁来访问或写入值,这就是我想要避免的 - 没有锁定/阻塞同时读/写。它模糊地说明了如果你不使用锁,它不会是“过程安全的”,但我真的不知道这意味着什么——如果不使用锁会发生什么坏事?
实现这一目标的最佳方法是什么?谢谢!
解决方案
由于某种原因,我忘记了可以以put
非阻塞方式进入队列!
我找到的解决方案是使用multiprocessing.Queue
with 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
,但是文档并没有明确(对我而言)如何做到这一点。
希望这可以帮助某人。
推荐阅读
- subscription - 使用订阅时报告列显示#Error
- docker - Docker 容器未加载 wwwroot 内容 Dotnet Core 3.1
- c# - 如何写入当前进程的 StdIn?
- javascript - 在焦点上异步填充数据列表选项(获取)
- graphql - 我可以更改 Hasura Graphql 端点吗?
- kubernetes - 用于 Statefulset 的 Kubernetes Admission webhook
- python - Python绘制具有不同数量元素的列表列表
- python - python threading:当多个线程之一失败时退出程序
- python - 如何在保持原始链表不变的情况下反转链表
- jquery - Django Ajax 多个文件表单重定向到 Json