【问题标题】:Splitting a string in chunks using multiprocessing使用多处理将字符串拆分为块
【发布时间】:2017-07-28 13:22:18
【问题描述】:

我正在通过 UDP 从微控制器获取数据。每个数据包都是一个十六进制字符串,我需要将它分成大小相等的块,然后再进行一些处理。但是,由于数据包相对较大(每个大约 700 个字符),因此将一个数据包分成块所需的时间大于数据包到达之间的时间。这会引入延迟,并且一半的数据会丢失。我不能使用 TCP/IP,因为系统需要实时运行。如何多处理以下行(甚至可以完成):

list_of_chunks = [packet[i:i+n] for i in range(0, len(packet), 16)]

【问题讨论】:

  • 多处理不太可能解决您的问题。如果拆分一个短字符串(700 个字符很短)需要在数据包之间完成太多时间,那么进程间通信的开销可能也会太高。我宁愿建议切换到更高效的实现(Cython?)甚至更高效的语言(C?)。
  • 我猜队列系统可能会满足您的要求。也许您可以对数据包进行排队并使用多线程消费者模式来处理它们。可能是 celery 是您正在寻找的。但不确定,我不知道你在哪里说实时你在谈论对某个地方的快速回复。
  • 对匆忙的开发人员的简单扩展技巧:运行 N 个 Python 服务器副本,侦听端口 P..P+N-1。让您的 MCU 循环顺序发送到端口 P..P+N-1。仅当您的数据包处理顺序无关紧要时才有效。
  • 你给了我一些想法,我会试试的,谢谢。
  • 您需要随机访问list_of_chunks 中的项目吗?可以编写一些东西,根据需要一次一个地顺序生成它们,或者快速为您提供列表中的任何单个元素而无需实际创建它(列表)。因此有效地生成所需的块,但仅在需要每个块时)。最后,由于数据是十六进制的,您可以通过尽快将其转换为二进制来将其大小减半。

标签: python split multiprocessing chunks


【解决方案1】:

我怀疑多处理(或多线程)会加快您想要完成的工作——开销太大。而是考虑展开循环。在这种情况下,您可以编写一个为您创建代码的脚本:

这就是我的意思:

PACKET_SIZE = 700
packet = [0] * PACKET_SIZE  # dummy packet

#list_of_chunks = [packet[i:i+16] for i in range(0, len(packet), 16)]
list_of_chunks = '\n    '.join('packet[{}:{}]'.format(i, i+16)
                                    for i in range(0, len(packet), 16))
print('list_of_chunks = [\n    ' + list_of_chunks + ']')

输出:

list_of_chunks = [
    packet[0:16]
    packet[16:32]
    packet[32:48]
    packet[48:64]
    packet[64:80]
    packet[80:96]
        ...
    packet[624:640]
    packet[640:656]
    packet[656:672]
    packet[672:688]
    packet[688:704]]

【讨论】:

  • 谢谢 - 这是一个好主意,我也有类似的想法。有没有一种方法可以通过某种方式使用这个 list_of_chunks “map”来返回数据包块的实际值?因为list_of_chunks中的列表元素是字符串类型的。
  • Alexander:生成的代码执行时将定义一个名为list_of_chunks的变量,它是一个列表,其元素是packet的对应片段。这个想法是,如果您事先知道块和数据包的大小,您可以为那个(或那些)案例预先编写代码,然后在您的程序中使用该代码。虽然当然也可以以编程方式执行生成的代码(或评估其中的表达式并返回结果),但这可能不会比您已经拥有的带有循环的代码更快)。
【解决方案2】:

不是读取 700 字节的数据,而是读取 16 字节并处理它的块。

例如:

while True:
    chunk = read(16)
    process (chunk)

这也可以在两个进程中完成:

#  Process 1
while True:
    chunk = read(16)
    fifo.push (chunk)

#  Process 2
while True:
    chunk = fifo.pop()
    process (chunk)

【讨论】:

    猜你喜欢
    • 2021-12-15
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 2019-03-15
    • 2016-01-02
    相关资源
    最近更新 更多