我知道,这不是一个好的答案,但您应该制作自己的简单数据流框架。
我写了一个原型 DF 服务器(和我的一个朋友一起),它有几个未实现的特性:它只能在消息中传递 Integer 和 Trigger 数据,并且它不支持并行性。我刚刚跳过了这项工作:组件的生产者端口有一个指向消费者端口的函数指针列表,这些函数指针在初始化时设置,并且它们调用它(如果列表不为空)。因此,当事件触发时,组件会执行数据流图的树状遍历。当他们使用整数和触发器时,它非常快。
此外,我编写了一个奇怪的组件,它有一个消费者和一个生产者端口,它只是简单地通过数据 - 但在另一个线程中。它的消费者例程很快就完成了,因为它只是放置数据并为生产者端线程设置一个标志。很脏,但它适合我的需要:它分离了 tree-walk 的长过程。
因此,正如您可能认识到的那样,它是用于快速任务的低流量异步系统,其中图形大小无关紧要。
不幸的是,您的问题与我的问题有很多不同,就像一个数据流系统可能与另一个不同一样,您需要一个同步、并行的流处理解决方案。
我认为,DF 服务器中最大的问题是调度程序。并发、冲突、线程、优先级……正如我所说,我只是跳过了问题,没有解决。你也应该跳过它。你也应该跳过其他问题。
调度员
在同步 DF 架构的情况下,所有组件必须每个周期运行一次,特殊情况除外。它们有一个简单的前提条件:输入数据是否可用?因此,如果数据可用,您应该只扫描组件,并将它们传递给空闲的调用者线程。在处理完所有这些之后,您将有 N 个剩余组件,这些组件尚未处理。您应该再次处理该列表。在第二次处理后,您将有 M 剩余。如果 N == M,则循环结束。
如果组件的数量低于 100,我认为某种相同的东西会起作用。
捆绑
是的,最好的绑定方式是可视化编程。在完成编辑器之前,类似配置的代码应该使用 insetad,例如:
// disclaimer: not actual code
Component* c1 = new AddComponent();
Component* c2 = new PrintComponent();
c2->format = "The result is %d\n";
bind(c1->result,c2->feed);
它易于编写,可读性强,还有其他愿望吗?
信息
您应该在组件的端口之间传递纯原始数据包。您只需要一个绑定列表,其中包含生产者和消费者端口的指针对,并包含“调度程序”使用的已处理标志。
通话问题
问题是生产者不应该调用消费者端口,而是组件;所有组件(类)变量和触发都在组件中。因此,生产者应该直接调用组件的公共入口点,将消费者的 ID 传递给它,或者它应该调用端口,该端口应该调用它所属的组件的任何方法。
所以,如果你能忍受一些限制,我说,继续写你的精简框架。这是一项很好的任务,但是编写小组件并看看,他们可以多么聪明地连接在一起构建一个伟大的应用程序是最终的乐趣。
如果您还有其他问题,请随时提问,我经常在这里扫描“数据流”关键字。
可能,您可以为您的程序找出一个更简单的数据流模型。