代码之家  ›  专栏  ›  技术社区  ›  terrace

C语言中的数据流库

  •  1
  • terrace  · 技术社区  · 16 年前

    如何在C中实现数据流(管道和过滤器、流处理、基于流)?而不是UNIX管道。

    我最近遇到 stream.py .

    流是具有流水线机制的可移植程序,可以实现数据流编程和简单的并行化。

    其思想是将一个函数的输出转换成另一个函数,并将其作为另一个函数的输入。虽然您已经可以使用函数组合来实现这一点,但这个包通过重载>>操作人员

    我想用C语言复制这种功能的一个简单版本。我特别喜欢 >> 运算符以避免函数合成混乱。维基百科指向 this hint 来自1990年的一篇Usenet帖子。

    为什么是C?因为我希望能够在微控制器和其他高级语言(Max、Pd*、Python)的C扩展中实现这一点。

    *(讽刺的是,Max和Pd都是用C写的,特别是为了这个目的,我在寻找一些赤裸裸的东西)

    3 回复  |  直到 6 年前
        1
  •  2
  •   ern0    16 年前

    我知道,这不是一个好答案,但你应该创建自己的简单数据流框架。

    我(和我的一个朋友一起)编写了一个原型DF服务器,它有几个尚未实现的特性:它只能在消息中传递整数和触发器数据,不支持并行。我刚刚跳过了这项工作:组件的生产者端口有一个指向消费者端口的函数指针列表,消费者端口是在初始化时设置的,它们会调用它(如果列表不是空的)。因此,当一个事件触发时,组件执行数据流图的树状遍历。当它们处理整数和触发器时,速度非常快。

    此外,我还编写了一个奇怪的组件,它有一个使用者和一个生产者端口,它只是简单地通过另一个线程传递数据。它的消费者例行程序很快就完成了,因为它只是将数据放入生产者端线程并设置一个标志。脏兮兮的,但它符合我的需要:它分离了长时间的树上行走过程。

    因此,正如您可能认识到的,它是一个用于快速任务的低流量异步系统,图形大小无关紧要。

    不幸的是,你的问题和我的问题有很多不同之处,就像一个数据流系统和另一个系统有很多不同之处一样,你需要一个同步、并行的流处理解决方案。

    我认为,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);
    

    写起来容易,可读性好,还有别的愿望吗?

    消息

    您应该在组件的端口之间传递纯原始数据包。您只需要一个绑定列表,其中包含生产者和消费者端口的指针对,并包含“dispatcher”使用的已处理标志。

    呼叫问题

    问题是,生产商不应该调用消费者端口,而应该调用组件;所有组件(类)变量和触发都在组件中。因此,生产者应该直接调用组件的公共入口点,将消费者的ID传递给它,或者应该调用端口,端口应该调用它所属组件的任何方法。


    所以,如果你能接受一些限制,我说,继续写你的lite框架吧。这是一项很好的任务,但是编写一些小组件,看看它们能有多聪明,构建一个伟大的应用程序才是终极乐趣。

    如果您还有其他问题,请随时提问,我经常扫描这里的“dataflow”关键字。

    也许,您可以为您的程序找到一个更简单的Dataflowsh模型。

        2
  •  1
  •   Dummy00001    16 年前

    我不知道有哪家图书馆有这样的用途。我的一个朋友在大学里做了类似的实验任务。这类系统的主要问题是性能低下(如果长管道中的功能很小,那么性能就很差)以及可能需要执行调度(检测死锁并提高优先级以避免管道缓冲区过载)。

    从我处理类似数据的经验来看,错误处理相当繁重。由于管道中的函数对上下文知之甚少(出于可重用性考虑,有意这样做),因此它们无法生成合理的错误消息。人们可以实现在线错误处理——将错误作为数据沿管道传递——但这需要在所有地方进行特殊处理,尤其是在输出上,因为流不可能与错误对应的输入相关联。

    考虑到这种方法的已知性能问题,我很难想象它会如何适合微控制器。就性能而言,没有什么比普通函数更好:可以为通过数据管线的每条路径创建函数。

    也许你可以找一些 Petri net 实现(模拟器或代码生成器),因为它们是流的理论基础之一。

        3
  •  1
  •   Community Mohan Dere    6 年前

    这很酷: http://code.google.com/p/libconcurrency/

    一个面向C的轻量级并发库,以对称协同路由作为主要控制流抽象。该库类似于状态线程,但使用协同路由而不是绿色线程。这简化了过程间调用,并在很大程度上消除了发信号时对互斥和信号量的需求。

    最终,协同路由调用也将能够在内核线程之间安全地迁移,因此可实现的可伸缩性因此远高于状态线程,状态线程是有目的的单线程。

    这个库的灵感来自道格拉斯·W·琼斯的“最小用户级线程包”。svn主干上的伪平台中性探测算法源自his代码。

    还有一种基于堆栈复制的更安全、更可移植的协同路由实现,其灵感来自sigfpe关于C语言中可移植延续的页面。复制比堆栈交换更可移植、更灵活,使复制与交换具有竞争力正在研究中。