Как эффективно обмениваться данными между несколькими потоками и процессами в Python?

1

У меня есть основной поток, запускающий Cmd из cmd2. Это позволяет мне интерактивно запускать новые потоки с помощью threading.Thread() выполняющих симуляции в режиме реального времени. Каждый раз, когда результаты моделирования выводятся put() в multiprocessing.Queue() режиме. multiprocessing.Queue(). Кроме того, я могу начать живые сюжеты, используя matplotlib.animate. Я читал, что matplotlib не является потокобезопасным, поэтому графики выполняются как multiprocessing.Process() matplotlib multiprocessing.Process() и get() результаты моделирования из очереди.

К сожалению, как только элементы из очереди собираются, они удаляются из очереди и недоступны для других потоков или процессов. Это означает, что я могу отправлять данные из потоков моделирования в процессы построения графиков, но не могу одновременно использовать результаты моделирования в своем основном потоке.

Решением может быть наличие двух очередей в каждом потоке моделирования: одна очередь для основного потока и одна очередь для процесса построения графика. Это, по-видимому, не оптимальное решение, а довольно сложное.

Кто-нибудь имеет представление о том, как реализовать какую-то нить-безопасную общую переменную, каждый поток и процессы могут читать и писать?

  • 1
    Очень трудно понять, что вы подразумеваете под потоками и процессами. Вы запускаете одну или несколько программ? Вы запускаете многопроцессорность или многопоточность или оба?
  • 0
    Как насчет добавления одной queue.Queue для основного потока для чтения?
Показать ещё 2 комментария
Теги:
multithreading
multiprocessing

1 ответ

0
Лучший ответ

В общем, есть два основных способа совместного использования данных между потоками и памятью:

  • передача сообщений
  • Общая память

Python рекомендует вам избегать написания кода, который использует общую память, и если вам нужно обмениваться данными между потоками и процессами, вы должны просто сделать копию данных и отправить их через очередь.

Если вам нужна фактическая разделяемая память, это чревато многими опасностями, поскольку вам обязательно нужно иметь дело с замками, чтобы избежать проблем. Кроме того, это может быть невозможно во многих объектах python, так как все объекты python в процессе имеют GIL.

Я читал, что matplotlib не является потокобезопасным

Код, который не является многопользовательским, обычно не является многопроцессорным.

Кто-нибудь имеет представление о том, как реализовать какую-то нить-безопасную общую переменную, каждый поток и процессы могут читать и писать?

Вы не хотите, или если вам действительно нужно, используйте базу данных.

  • 2
    Хотя я согласен с большинством мнений об этом ответе, я считаю, что код предложения, который не является многопоточным безопасным, обычно не является многопроцессорным безопасным, либо является совершенно правильным. Основной причиной того, что функции не являются потокобезопасными, является общее глобальное состояние (т. Е. Глобальные переменные и файлы и т. Д.). Обычно между процессами существует гораздо более жесткая изоляция, поэтому они не будут использовать даже глобальные переменные или временные файлы. Поэтому, в большинстве случаев, вполне возможно, что код является многопроцессорным, но не потокобезопасным.
  • 0
    Спасибо за отзыв, особенно комментарий о "странной настройке". Я реструктурировал весь код и начал симуляции как разные процессы, которые записывают результаты симуляции в очередь. Результаты собраны в другой ветке и доступны для основной ветки. Мне удалось настроить matplotlib неблокирующим способом для живых графиков, поэтому matplotlib запускается в основном потоке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню