具有有序完成的异步线程池

时间:2017-07-17 01:31:46

标签: c++ multithreading

在基本线程池模式中,主线程将任务推送到请求队列。线程池以未指定的顺序执行任务,并在每个任务完成时将通知发布到主事件循环。

在某些情况下,您可以从额外的吞吐量中受益,但您只能按指定的顺序使用已完成的任务。我们假设你有一个音频应用程序。主线程发送要由线程池处理的音频块。可以同时处理多个块并且不按顺序完成,但是主线程必须按照提交的顺序将每个处理过的块推送到音频流。

我的第一个想法是使用某种线程安全的队列(链接列表或双端队列)来处理所请求的任务,并让主线程在等待完成的"标记在队列的头部,然后取消链接并使用数据。在进一步的思考中,我想到这个问题必须已经多次解决了。这通常是如何在C ++中完成的?

3 个答案:

答案 0 :(得分:1)

我们在许多服务器应用程序中使用了GNU许可runloop。也许它会合适吗?

#include <memory>
#include <cstdlib>
#include <corvusoft/core/run_loop.hpp>

using namespace std;
using corvusoft::core::RunLoop;

int main( const int, const char** )
{
    const auto task = [ ]( void ) { return error_code( ); };

    auto runloop = make_shared< RunLoop >( );
    runloop->launch( task );
    runloop->launch( task );
    runloop->launch( task );
    runloop->launch( [ runloop ]( void )
    {
        runloop->wait( ); //wait for other tasks to complete.

        //perform additional logic with the computed result.

        runloop->stop( ); //causes start to return.
        return error_code( );
    } );

    runloop->start( );

    return EXIT_SUCCESS;
}

答案 1 :(得分:1)

你可以看看boost :: io_service你的线程池问题。它易于使用和实施。

boost asynchronous io service

编辑:

您可以在C ++ 11中使用std :: async和std :: future解决此加入问题。最简单的方法可能是这样的:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>

template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end)
{
  auto len = end - beg;
  if (len < 1000)
    return std::accumulate(beg, end, 0);

  RAIter mid = beg + len/2;
  auto handle = std::async(std::launch::async,
                           parallel_sum<RAIter>, mid, end);
  int sum = parallel_sum(beg, mid);
  return sum + handle.get();
}
int main()
{
  std::vector<int> v(10000, 1);
  std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}

handle.get()同步返回std :: future对象,以便您的parallel_sum以多个线程执行,并通过有序线程连接返回结果。因此,通过更改此示例,您可以使用并行块处理音频数据,并按顺序返回最终结果。

std :: async解释和原始示例link

答案 2 :(得分:0)

两种最常见的方法是使用OpenMP或MPI实现。我假设您的线程将共享数据(音频文件),因此您需要学习OpenMP。

一个好的起点是:https://computing.llnl.gov/tutorials/openMP/