并发快速排序的面向对象解决方案

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);
}

 

posted @ 2015-10-17 11:11  wu_overflow  阅读(228)  评论(0编辑  收藏  举报