我有以下情况。数据(在这种情况下为数据包)由Python函数实时处理,因为每个数据流都是。因此,每个数据都被接收并转换为python对象。在该对象上完成了一个轻量级算法,它返回一个输出(小字典)。然后丢弃该对象并处理下一个对象。我有那个程序在运行。
现在,对于每个对象,算法将生成一个输出数据的小字典。需要通过单独的第二算法(也是实时)处理该字典。我设想我的代码运行两个进程。我需要让第二个过程“监听”第一个的输出。
那么如何在python中编写第二个算法,以便它可以监听并接受第一个算法产生的数据?举一个具体的例子,假设第一个算法应用时间戳,然后传递给缓冲区,第二个算法侦听 - 它从缓冲区中获取并处理它。如果缓冲区中没有任何内容,则只要出现某些内容,它就会处理它。
答案 0 :(得分:0)
如果您需要使用不同的进程(而不是单个进程中的多个函数),那么消息传递队列可能对您有用吗?因此,您的第一个进程会执行任何操作,并将结果放入消息队列中,这是您的第二个进程正在侦听的。
显然有很多选项,但根据你的描述,这听起来像是一种合理的方法。
答案 1 :(得分:0)
我知道这应该是一个评论,因为它并没有真正回答你的问题,而是指出了一个替代方案,但我不能将其纳入评论中,所以在这里:
从流程构建流水线看起来像一个干净的解决方案,但有一些问题需要考虑:
如果您不使用共享内存,则必须在过程之间将数据作为消息传递。这意味着每个进程都必须对其输入进行反序列化并将其输出序列化,以便对中间结构进行简单的转换。只是做繁忙的序列化和反序列化,你会失去很多效率。
假设您在瀑布模型中设计系统(第一个进程将数据传递给第二个进程,将数据传递给第三个进程,等等),如果链中的某个进程死亡,那么整个管道破裂。因此,它不一定比单一流程管道更强大(事实上,我希望它比单一流程解决方案更容易破解)
您希望您的管道易于调整。因此:确保您拥有每个“转换器”都可读取的内存数据格式(例如,每个转换器识别出具有少量标准化属性的字典,以确定它是否可以在其上工作。
然后将每个转换器编写在它自己的模块中(这有助于使它们可以通过非常少的额外脚手架轻松(单元)测试)。让您的主应用程序导入您需要的所有转换器模块,并使用转换器注册表(基本上是要调用的函数列表)注册其转换器。在主应用程序中,您读取输入,将其转换为内存中的字典,依次运行所有已注册的转换器并输出结果。
这仍然可以轻松测试和调整,因为您只需更改导入和注册的转换器即可。
您甚至可以在流程运行时更改配置(运行转换器),方法是存储要导入并转换到文件中的转换器的信息,如果要在流程运行时调整,请发送SIGHUP(在Unix上,无论如何 - 在Windows上你必须找到另一种方式来指示进程),这将导致它重新读取它的配置文件并调整它在数据上运行的转换器列表。这并不难实现。
如果您不需要在多个核心上运行的速度,则效率更高,破坏的可能性更小,更容易推理和支持。
基本想法看起来有点像这样(没有所有的花里胡哨):
# this is transformator_a.py
def transform(data):
return do_very_cool_stuff_to(data)
# this is transformator_b.py
import random
def transform(data):
if can_i_handle_this(data):
return do_some_more_cool_stuff_to(data)
else:
return data
def can_i_handle_this(data):
# this is a very picky transformator - it's not always sure it
# can handle the data
i = random.randint(1, 5)
return i == 2
# this is the main app
import transformator_a
import transformator_b
registered_transformators = [ transformator_a.transform,
transformator_b.transform ]
while True:
data = deserialize_data_unit_from_external_input_stream()
for transform in registered_transformators:
try:
data = transform.transform(data)
except SomeExcpetionsYouWantToHandle:
# might not be fatal to the rest of the pipeline.
# check whether data is still viable,
# continue if so, exit process if not - or you might
# just drop this data unit
ensure_we_have_viable_data(data)
serialize_data_unit_to_output_stream(data)