1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
...
#include "thread_safe_queue.cpp"
...
class thread_pool
{
typedef function_wrapper task_type;
std::atomic_bool done;
thread_safe_queue<task_type> pool_work_queue;
std::vector<std::unique_ptr<work_stealing_queue> > queues;
std::vector<std::thread> threads;
join_threads joiner;
static thread_local work_stealing_queue* local_work_queue;
static thread_local unsigned my_index;
void worker_thread(unsigned my_index_)
{
my_index=my_index_;
local_work_queue=queues[my_index].get();
while(!done)
{
run_pending_task();
}
}
...
public:
thread_pool():
joiner(threads),done(false)
{
unsigned const thread_count=std::thread::hardware_concurrency();
...
};
template<typename T>
struct sorter
{
thread_pool pool;
std::list<T> do_sort(std::list<T>& chunk_data)
{
...
}
};
template<typename T>
std::list<T> parallel_quick_sort(std::list<T> input)
{
if(input.empty())
{
return input;
}
sorter<T> s;
std::cout << "Beginning sort..." << std::endl;
return s.do_sort(input);
}
int main()
{
std::cout << "About to create a list that needs sorting...." << std::endl;
std::list<int> my_list = {213,3,123,1,234232,41,0,-4,6,2,333,420,1337,88568568,4564564,456465456,33234234,2343,234222,3344555};
std::cout << "Done creating my_list...." << std::endl;
std::cout << "Submitting to sorter now" << std::endl;
std::list<int> result = parallel_quick_sort(my_list);
std::cout << "Now printing results" << std::endl;
for (auto list_item : result){
std::cout << list_item << "\n";
}
std::cout << "Finished" << std::endl;
}
//https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
|