在我们的应用程序中,我们有一个来自LoRa收发器的数据流,我只想由一个主要进程读取它。不过,我希望能够通过单独的过程来处理此数据,以免减慢主过程的速度,因此它始终接收消息并将其发送给四个读取传感器数据的发送器。主进程(“协调器”)和单独的进程将在Raspberry Pi 4中运行。
我想一直保持所有这些进程的生命,并能够与协调器共享内存,该协调器将展开每个传入消息的字节并将其保存在n个不同的pandas数据帧中,每个将读取它们的子进程都保存一个。在这种情况下,我们将有4个发送器,4个要由协调器管理的数据流,4个在协调器中的熊猫数据帧,4个运行和处理数据的进程,这些数据已经存储在协调器的数据帧中。关于此主题,我有四个问题,希望您能为我提供帮助。我试图组织有关其对我的重要性的问题。最大的问题是能够正确地声明数据帧并能够共享它们(1和4.2)。同时读/写将是第二(2),而动态内存分配将是最后(点3和4.1)。很抱歉,我的帖子很长,希望您至少能对我有所帮助。谢谢!
第一个问题
通过阅读文档,我可以看到我可以创建一个足够大的固定大小的数据帧,将其滚动以最终保留最新数据,因此我认为这不是问题。不过,当从另一个进程连接到此DataFrame时,我看到需要定义它的类型和大小。这些小的子进程可能会死掉并存活下来,并且可能会在创建空数据帧之后从协调器写入的文件中读取共享内存名称,从而加入协调器的内存。
这来自docs(https://docs.python.org/3/library/multiprocessing.shared_memory.html):
>>>...(this is happening in another process after shared memory with name 'psm_21467_46075' has already been created)
>>> existing_shm = shared_memory.SharedMemory(name='psm_21467_46075')
>>> # Note that a.shape is (6,) and a.dtype is np.int64 in this example
>>> c = np.ndarray((6,), dtype=np.int64, buffer=existing_shm.buf)
在第二个过程中创建c时,必须声明其大小和类型以及名称。在示例中,它是一个numpy数组,但是对于熊猫数据框,声明将如何更改?
第二个问题
将按以下方式创建此熊猫数据框:第一列具有时间戳,第二列至n列具有传感器值,最后(n+1
)列具有标志。我打算从子进程中更改此标志,以便知道传入缓冲区的哪一部分已被处理。对于每个新数据包,协调器将汇总旧数据,并使用带有“ false” processed 标志的新数据设置数据帧的末尾。
为了保持在DataFrame中的位置,我将使用一个整数值posInDf
来衡量尚未处理数据的起始位置。因此,子进程从该位置读取数据帧(我们将其称为a
),直到结束(m
)为止,并将此数据(n+1 x m-a
数据帧)带到本地副本(因为协调器将不断引入新数据),对其进行操作,将其保存在csv中(用于备份),将其上传到服务器,最后,更改协调器DataFrame中的标志。
在这种情况下
posInDf
给定的引用(posInDf
的值将由子进程在一行和下一行中读取)会因为行之间经过的时间而从posInDef
开始的数据帧中分配一个具有True processed 标志的ma元素)?只需进行一行编辑即可(同时访问DataFrame和当前posInDef
值)?第三个问题
我正在协调器中定义一个固定大小的DataFrame,但我不知道是否有可能使其大小可变。新数据进入,被写入DataFrame的顶部,并随着新数据包的掉落而开始变旧。子进程可以从其最后一个元素(底部)读取DataFrame,直到第一个或第二个元素为止,然后 trim 修剪该数据。当新数据包到来时,DataFrame将再次填充,但会不断地修剪。
是否可以使用多处理中的shared_memory做到这一点?如果可能的话,这会比第一种方法有效吗?
第四个问题
通过子进程(从Internet捕获的指令)发送给协调器的配置列表,可能会要求协调器向发送方询问比现在接收的更多或更少的变量。已经从接收数据。在这种情况下,DataFrame列将需要根据此数量的变量来增大或缩小。
再次:任何帮助将不胜感激。谢谢!