在我之前的问题中,我使用带有输入,转换和输出过滤器的C ++(Linux)实现了TBB管道:
incorrect output with TBB pipeline
输入过滤器正在从文本文件中读取数据(C结构)并传递给Transform过滤器。 Transform过滤器正在更新数据并将其传递给Output过滤器。输出过滤器将其存储在光盘上。一个简单的读写应用程序。
现在,我正在寻找创建一个MAIN应用程序。 MAIN应用程序将在开始时创建一个带有三个过滤器的TBB管道:
OutputFilter:接收它并将信息返回给主应用程序。
在开始时,InputFilter将不会执行任何操作,因为data / C Structure将为空。所以它将循环或等待。
MAIN应用程序将从文件中读取数据,并将信息传递给InputFilter(如果需要)。然后InputFilter将处理它并将其传递给下一个过滤器,依此类推。所以不同的是:
输入由MAIN应用程序控制,而不是在InputFilter中控制(如我之前所做的那样)。一种方法是通过引用传递data / C结构到InputFilter,然后通过MAIN应用程序更新它。但问题是:
控件永远不会从InputFilter返回到MAIN应用程序。任何帮助将非常感谢! !
答案 0 :(得分:2)
我已经修改了thread_bound_filter documentation页面中的示例,以便将第一个过滤器设置为线程绑定。它工作正常,我认为这是你需要的:
#include <iostream>
#include "tbb/compat/thread"
#include "tbb/pipeline.h"
using namespace tbb;
using namespace std;
char InputString[] = "abcdefg\n";
class InputFilter: public thread_bound_filter {
char* my_ptr;
public:
void* operator()(void*) {
if (*my_ptr)
return my_ptr++;
else
return NULL;
}
InputFilter()
: thread_bound_filter( serial_in_order ), my_ptr(InputString)
{}
};
class OutputFilter: public filter {
public:
void* operator()(void* item) {
std::cout << *(char*)item;
return NULL;
}
OutputFilter() : filter(serial_in_order) {}
};
void RunPipeline(pipeline* p) {
p->run(8);
}
int main() {
// Construct the pipeline
InputFilter f;
OutputFilter g;
pipeline p;
p.add_filter(f);
p.add_filter(g);
// Another thread initiates execution of the pipeline
thread t(RunPipeline, &p);
// Process the thread_bound_filter with the current thread.
while (f.process_item()!=thread_bound_filter::end_of_stream)
continue;
// Wait for pipeline to finish on the other thread.
t.join();
return 0;
}
当然,您可能希望添加更多过滤器,更改其类型(第一个必须是串行的),更改令牌数,使用task::enqueue()
而不是显式线程,将process_item()
替换为try_process_item()
为了避免在令牌数超过时被阻挡在内部但是一般的想法是相同的,你可以将控件返回到处理过滤器的线程。