并发快速排序的面向对象解决方案
template<typename T>
struct Sorter
{
struct ChunkToSort
{
std::list<T> data;
std::promise<std::list<T>> promise;
};
ThreadSafeStack<ChunkToSort> chunks;
std::vector<std::thread> threads;
size_t const maxThreadCount;
std::atomic<bool> endOfData;
Sorter():
maxThreadCount(std::thread::hardware_concurrency () - 1),
endOfData(false)
{}
~Sorter()
{
endOfData = true;
for (size_t i = 0; i < threads.size(); ++i){
threads[i].join();
}
}
void trySortChunk()
{
auto chunkPtr = chunks.pop ();
if (chunkPtr != nullptr){
sortChunk(chunkPtr);
}
}
std::list<T> sortData(std::list<T>& chunkData)
{
if (chunkData.empty ()){
return chunkData;
}
std::list<T> result;
result.splice (result.begin (), chunkData, chunkData.begin ());
auto const& partitionVal = result.front();
auto divideIterator = std::partition(chunkData.begin (),
chunkData.end (),
[&](T const& val)
{return val < partitionVal;});
ChunkToSort newLowerChunk;
newLowerChunk.data.splice (newLowerChunk.data.end (), chunkData,
chunkData.begin (), divideIterator);
auto newLower = newLowerChunk.promise.get_future ();
chunks.push(std::move(newLowerChunk));
if(threads.size () < maxThreadCount){
threads.push_back (std::thread(&Sorter<T>::sortThread, this));
}
std::list<T> newHigher(sortData (chunkData));
result.splice (result.end (), newHigher);
while(newLower.wait_for(std::chrono::seconds(0)) !=
std::future_status::ready){
trySortChunk ();
}
result.splice (result.begin (), newLower.get ());
return result;
}
void sortChunk(std::shared_ptr<ChunkToSort> const& chunk)
{
chunk->promise.set_value (sortData (chunk->data));
}
void sortThread()
{
while(endOfData){
trySortChunk();
std::this_thread::yield();
}
}
};
template<typename T>
std::list<T> parallelQuickSort(std::list<T>& input)
{
if (input.empty ()){
return input;
}
Sorter<T> sorter;
return sorter.sortData (input);
}