6

我一直在寻找 C++ 中可重用的执行管道库(作业调度程序库?)。我在Boost中找不到任何东西。所以我最终找到了两个候选人:

我错过了其他候选人吗?有人用过吗?它们在并行 io 和多​​线程方面有多好?这些库似乎仍然缺少依赖项处理。例如,我似乎不清楚如何编写如下内容:

$ cat /dev/urandom | tr P Q | head -3

在这个非常简单的例子中,管道是自下而上的,当进程停止拉动时,第一个cat停止执行。head

但是,在以下情况下,我看不到如何从多线程和/或并行 io 中受益:

$ cat /raid1/file1 /raid2/file2 | tr P Q > /tmp/file3

我无法说:tr当 8 个处理器可用时在 7 个线程上执行。

4

3 回答 3

3

您正在寻找的是一个数据流框架。管道是一种特殊形式的数据流,其中所有组件都有 1 个消费者和 1 个生产者。

Boost 支持数据流,但不幸的是,我对 Boost 并不熟悉。这是链接:http ://dancinghacker.com/code/dataflow/dataflow/introduction/dataflow.html

无论如何,您应该将组件编写为单独的程序并使用 Unix 管道。特别是,如果您的数据特征是(或可以轻松转换为)行/文本。

还有一种选择是编写自己的数据流事物。这并不难,尤其是当您有限制时(我的意思是管道:1-消费者/1-生产者),您不应该实现完整的数据流框架。管道只是将某种函数绑定在一起,将一个结果传递给下一个 arg。数据流框架是关于组件接口/模式和绑定技术的。(很有趣,我写了一个。)

于 2013-04-01T21:54:00.893 回答
2

我会给线程构建块http://threadingbuildingblocks.org/一个尝试。它是开源和跨平台的。维基百科的文章很不错:http ://en.wikipedia.org/wiki/Intel_Threading_Building_Blocks

于 2013-04-04T17:27:05.170 回答
2

我今天刚读到RaftLib,它使用模板和类来创建称为“内核”的管道元素。除了并行数据流之外,它还允许像您展示的 Bash 示例一样使用串行管道。来自首页的Hello world 示例

#include <raft>
#include <raftio>
#include <cstdlib>
#include <string>

class hi : public raft::kernel
{
public:
    hi() : raft::kernel()
    {
       output.addPort< std::string >( "0" ); 
    }

    virtual raft::kstatus run()
    {
        output[ "0" ].push( std::string( "Hello World\n" ) );
        return( raft::stop ); 
    }
};


int
main( int argc, char **argv )
{
    /** instantiate print kernel **/
    raft::print< std::string > p;
    /** instantiate hello world kernel **/
    hi hello;
    /** make a map object **/
    raft::map m;
    /** add kernels to map, both hello and p are executed concurrently **/
    m += hello >> p;
    /** execute the map **/
    m.exe();
    return( EXIT_SUCCESS );
}
于 2016-05-31T16:44:55.810 回答