【问题标题】:How to share data between multiple threads and processes in Python effectively?如何有效地在 Python 中的多个线程和进程之间共享数据?
【发布时间】:2018-10-14 07:31:23
【问题描述】:

我有一个从cmd2 运行的主线程Cmd。这使我可以使用threading.Thread()“实时”执行模拟以交互方式启动新线程。每个时间步的模拟结果都是put() 中的multiprocessing.Queue()。此外,我可以使用matplotlib.animate 开始实时绘图。我读到matplotlib 不是线程安全的,所以这些图以multiprocessing.Process()get() 的模拟结果从队列运行。

不幸的是,一旦收集了队列中的项目,它们就会从队列中删除,并且不能用于其他线程或进程。这意味着我可以将数据从模拟线程发送到绘图进程,但不能在我的主线程中同时使用模拟结果。

一种解决方案可能是在每个模拟线程中有两个队列:一个队列到主线程,一个队列到绘图进程。这似乎不是最佳解决方案,而是一个相当复杂的解决方案。

有没有人知道如何实现某种线程安全的共享变量,每个线程和进程都可以读取和写入?

【问题讨论】:

  • 很难理解线程和进程的含义。你启动一个或多个程序?您运行多处理或多线程或两者兼而有之?
  • 添加一个queue.Queue 供主线程读取怎么样?
  • @JohanL 我将threading.Thread()multiprocessing.Process() 用于不同的任务(线程用于模拟,进程用于实时绘图)。
  • 你有一个奇怪的设置,通常你想要做 CPU 绑定的东西,比如多进程中的模拟,而像绘图这样的 UI 东西通常必须在主线程中(大多数 UI 框架要求你只有一个 UI 线程)。

标签: python multithreading multiprocessing


【解决方案1】:

一般来说,线程和内存之间共享数据主要有两种方式:

  • 消息传递
  • 共享内存

Python 鼓励您避免编写使用共享内存的代码,如果您需要在线程和进程之间共享数据,您应该只复制数据并通过队列发送。

如果您需要实际的共享内存,这会带来很多危险,因为您必须处理锁以避免问题。此外,这对于许多 python 对象来说可能是不可能的,因为一个进程中的所有 python 对象都共享一个 GIL。

我读到 matplotlib 不是线程安全的

不是多线程安全的代码通常也不是多进程安全的。

有没有人知道如何实现某种线程安全的共享变量,每个线程和进程都可以读取和写入?

你不想,或者如果你真的必须,使用数据库。

【讨论】:

  • 虽然我同意这个答案的大部分观点,但我确实认为不是多线程安全的代码通常也不是多进程安全的句子是非常正确的。函数不是线程安全的主要原因是共享全局状态(即全局变量和文件等)。通常,进程之间存在更紧密的隔离,因此它们甚至不会共享全局变量或临时文件。因此,大多数时候,代码很有可能是多进程安全的,而不是线程安全的。
  • 感谢您的反馈,尤其是关于“奇怪的设置”的评论。我重组了我的整个代码并将模拟作为不同的进程开始,这些进程将模拟结果写入队列。结果被收集在另一个线程中并提供给主线程。我设法以非阻塞方式为实时图配置了 matplotlib,因此 matplotlib 在主线程中运行。
猜你喜欢
  • 1970-01-01
  • 2020-02-18
  • 2012-03-19
  • 2018-06-18
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多