По какой-то причине я забыл, что можно put
в очередь неблокирующим способом!
Решение, которое я нашел, заключается в использовании multiprocessing.Queue
с 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
вместо очереди,но документы не дают понять (для меня), как это сделать.
Надеюсь, это кому-нибудь поможет.