在基本线程池模式中,主线程将任务推送到请求队列。线程池以未指定的顺序执行任务,并在每个任务完成时将通知发布到主事件循环。
在某些情况下,您可以从额外的吞吐量中受益,但您只能按指定的顺序使用已完成的任务。我们假设你有一个音频应用程序。主线程发送要由线程池处理的音频块。可以同时处理多个块并且不按顺序完成,但是主线程必须按照提交的顺序将每个处理过的块推送到音频流。
我的第一个想法是使用某种线程安全的队列(链接列表或双端队列)来处理所请求的任务,并让主线程在等待完成的"标记在队列的头部,然后取消链接并使用数据。在进一步的思考中,我想到这个问题必须已经多次解决了。这通常是如何在C ++中完成的?
答案 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你的线程池问题。它易于使用和实施。
编辑:
您可以在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。