【问题标题】:Python - Merge data from multiple thread instancesPython - 合并来自多个线程实例的数据
【发布时间】:2016-09-26 14:09:12
【问题描述】:

我目前正在从事一个项目,该项目涉及将两个设备连接到 python 脚本,从中检索数据并输出数据。

代码大纲:

• 扫描配对设备

• 找到的配对设备创建线程实例(连接的两个设备 = 两个线程实例)

• 数据在线程中打印,即每个实例都有一个单独的 数据包

基本上当两个设备连接时,我的线程类的两个实例被创建。每个线程实例返回不同的数据包。

我的问题是:有没有办法可以将两个数据包合并为一个数据包?

对此的任何帮助表示赞赏:)

【问题讨论】:

  • 感谢您提供代码概述,但我认为 MCVCE 也会有所帮助。
  • 您可以将来自两个线程的数据放在一个结构(如列表)中,有两个条件:使用相对较小的块并使用locks 访问该结构。

标签: python multithreading


【解决方案1】:

我假设您正在使用threading 模块。

Python 中的线程

对于 CPU 活动,Python 不是多线程的。解释器仍然对大多数操作使用 GIL(全局解释器锁),因此在 python 脚本中线性化操作。然而,线程很好地进行 IO,因为在线程等待 IO 时可以唤醒其他线程。

想法

由于 GIL,我们可以只使用标准列表来组合我们的数据。这个想法是将相同的列表或字典传递给我们使用args 参数创建的每个线程。见pydoc for threading

我们的简单实现使用两个线程来展示它是如何完成的。在实际应用程序中,您可能会使用线程组或类似的东西..

实施

def worker(data):
    # retrieve data from device
    data.append(1)
    data.append(2)
l = []
# Let's pass our list to the target via args.
a = Thread(target=worker, args=(l,))
b = Thread(target=worker, args=(l,))
# Start our threads
a.start()
b.start()
# Join them and print result
a.join()
b.join()
print(l)

进一步的想法

如果您希望 100% 正确并且不依赖 GIL 来线性化对您的列表的访问,您可以使用简单的互斥锁来锁定和解锁,或者使用实现正确锁定的 Queue module

根据数据的性质,字典可能更方便通过某些键连接数据。

其他注意事项

应仔细考虑线程。 asyncio 等替代方案可能更适合。

【讨论】:

  • 此处描述的“进一步思考”的实现可以使用Queue(来自队列模块)。它实现了线程安全所需的锁定。
  • 这很好用,谢谢。当我将它添加到我的代码中时,它结合了来自两个设备的所有数据,但是直到我中断脚本它才打印出来。当有新数据要发送时,我应该如何打印数据?
  • 您可以使用第三个线程来消耗队列/列表并打印它。根据数据可能在线程内打印仍然可行吗?一些 python 人正在使用的另一种方法是使用多进程来生成一个处理设备的进程和另一个继续读取和计算的进程。见docs.python.org/2/library/multiprocessing.html
  • 如何将数据多线程化到数据库中并从那里检索?突然之间,输入与输出分离。是的,这假设数据库能够同时处理多个连接,但这些并不罕见。它们中的大多数都是为此而构建的。
【解决方案2】:

我的一般建议:避免使用这些东西

  • 避免线程
  • 避免 Python 中的多处理模块
  • 避免使用 Python 中的 futures 模块。

使用像http://python-rq.org/这样的工具

好处:

  • 您需要很好地定义输入和输出数据,因为只能传递可序列化的数据
  • 你们有不同的口译员。
  • 没有死锁
  • 更易于调试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多