C ++线程类设计来自非线程类

时间:2010-03-15 09:57:35

标签: c++ multithreading class boost-thread

我正在开发一个进行音频编码/解码的库。如果可用,编码器应能够使用多个核(即多个线程,使用升压库)。我现在拥有的是一个执行所有编码相关操作的类。

我想采取的下一步是使该类具有线程。所以我想知道如何做到这一点。

我考虑过编写一个线程类,为n个内核创建n个线程,然后使用适当的参数调用编码器。但也许这是一个矫枉过正,并且不需要另一个类,所以我将利用“用户界面”进行线程创建。

我希望有任何建议。

编辑:我被迫使用多个线程进行预处理,使用CUDA创建输入数据的统计信息。因此,如果系统中有多个卡,并行使用它们的唯一方法是创建多个线程。

示例: 4个文件,4个不同的计算单位(单独的内存,唯一的设备ID)。每个文件都应在一个计算单元上执行。

我现在拥有的是:

class Encoder {
[...]
public:
    worker(T data, int devId);
[...]
}

所以我认为最好的方法是从main()

中调用worker
boost::thread w1(&Encoder::worker, data0, 0);
boost::thread w2(&Encoder::worker, data1, 1);
boost::thread w3(&Encoder::worker, data2, 2);
boost::thread w4(&Encoder::worker, data3, 3);

而不是实现线程类。

4 个答案:

答案 0 :(得分:2)

如果您的编译器支持,请查看OpenMP。它可以像添加编译器标志和喷涂几个#pragma一样简单。

答案 1 :(得分:1)

我认为问题更多的是设计层面,你能详细说明你有什么课吗?我也在使用CUDA,通常会创建一个接口(也就是Facade模式)来使用特定于体系结构(CUDA)的层。

编辑:阅读更新界面后,我认为您做的是正确的。 将Encoder逻辑保留在类中,并使用普通的boost :: threads来执行不同的工作单元。只需关注编码器方法中的线程安全性。

答案 2 :(得分:1)

您当前的建议仅在Encoder::workerstatic时才有效。我认为是这样的。如果您当前的实现支持一种优雅地中止编码作业的方法,那么问题就在于此。我想你的代码中有一些方法:

while( MoreInputSamples ) {
    // Do more encoding
}

可以使用一些附加条件修改此操作,以检查作业是否已收到中止信号。我经常进行视频解码,我喜欢这样的解码器类:

class Decoder {
public:
    void DoOneStepOfDecoding( AccessUnit & Input );
}

输出通常会转到某个环形缓冲区。这样,我可以轻松地将其包装在单线程和多线程场景中。

答案 3 :(得分:1)

前面的代码

  boost::thread w1(&Encoder::worker, data0, 0);

在工人静止之前无效。

审核时间表中有Boost.Task允许您异步调用任何可调用的内容,如下所示

  boost::tasks::async(
    boost::tasks::make_task( &Encoder::worker, data0, 0) ) );

这会导致在默认的线程池上调用Encoder :: worker。该函数返回一个句柄,允许知道任务何时执行。