基于栈的快排模板

线程安全栈
promise的用法
list::splice实现list拼接的功能。将源list的内容部分或全部元素删除,拼插入到目的list。
boost线程中的yield方法:可以将本线程的CPU时间片放弃,并允许其他线程运行。
如果你想直接告诉编译器 T::const_iterator 是类型而不是变量,只需用 typename修饰。
c++ partition

#include <iostream>
#include <list>
#include <future>
#include <vector>
#include <thread>
#include <atomic>
#include <algorithm>
#include <memory>
#include <boost/shared_ptr.hpp>
#include "tsafe_stack.h"
using namespace std;
template<typename T>
class sorter
{
    struct chunk_to_sort {
        list<T> data;
        promise<list<T> > promise;
    };
    tsafe_stack<chunk_to_sort> chunks;//未排序块所在栈
    vector<thread> threads;//线程分组
    const unsigned  max_threads_count;//最大线程数量
    atomic<bool> end_of_data;
    /*boost::shared_ptr<chunk_to_sort> to_boost(const shared_ptr<chunk_to_sort>& p) {
     return boost::shared_ptr<chunk_to_sort>(p.get(), [p](...) mutable { p.reset(); });
    }*/
    void try_sort_chunk() { //一个块出栈,并将其排序  boost::
        boost::shared_ptr<chunk_to_sort > chunk = chunks.pop();
        if (chunk) {
            sort_chunk(chunk);
        }
    }
public:
    sorter() :
        max_threads_count(thread::hardware_concurrency() - 2),
        end_of_data(false)
    {
        cout << "开启多线程快速排序,线程数量:" << max_threads_count << endl;
    }
    ~sorter() {
        end_of_data = true;
        for (unsigned i = 0; i < threads.size(); ++i) {
            threads[i].join();//等待线程们结束
        }
        cout << "结束多线程快速排序" << endl;
    }
    list<T> do_sort(list<T>& chunk_data) {
        if (chunk_data.empty()) {
            return chunk_data;
        }
        list<T> result;
        result.splice(result.begin(), chunk_data, chunk_data.begin());
        T const& partition_val = *result.begin();
        typename list<T>::iterator divide_point =//完成排序——A
            partition(chunk_data.begin(), chunk_data.end(),
                [&](T const& val) { return val < partition_val; });
        chunk_to_sort new_lower_chunk; //将块压入栈中
        new_lower_chunk.data.splice(new_lower_chunk.data.end(),
            chunk_data, chunk_data.begin(), divide_point);
        future<list<T> > new_lower = new_lower_chunk.promise.get_future();
        chunks.push(move(new_lower_chunk)); //将块压入栈中
        if (threads.size() < max_threads_count) {//仍有处理器可以分配
            threads.push_back(thread(&sorter<T>::sort_thread, this));
        }
        list<T> new_higher(do_sort(chunk_data));
        result.splice(result.end(), new_higher);
        while (new_lower.wait_for(std::chrono::seconds(0)) //等待其他线程处理
            != future_status::ready) {
            try_sort_chunk();
        }
        result.splice(result.begin(), new_lower.get());
        return result;
    }
private:
    void sort_chunk(boost::shared_ptr<chunk_to_sort> const& chunk) {
        chunk->promise.set_value(do_sort(chunk->data));
    }
    void sort_thread() {
        while (!end_of_data) {
            try_sort_chunk();
            this_thread::yield();
        }
    }
};
template<typename T>
list<T> parallel_quick_sort(list<T>& input) {
    if (input.empty()) {
        return input;
    }
    sorter<T> s;
    return s.do_sort(input);
}
int main()
{
    std::cout << "Hello World!\n";
    list<int> l{ 2,34,543,365,875923,426468,33,9656 };
    list<int> ans=parallel_quick_sort(l);
    for (auto& it : l) {
        cout << it << " ";
    }
    return 0;
}

在A处完成了数据排序,如果不是内置类型,需要提供<重载。
chunk_to_sort 结构体的拷贝构造函数可能有问题,该代码会报错。

上一篇:大文件上传之--切片上传和断点续传


下一篇:Java中如何判断两个对象是否相等