下面的代码触发错误:
错误 1 错误 C2248:“std::promise<_Ty>::promise”:无法访问在类“std::promise<_Ty>”中声明的私有成员
我该如何解决?
非常感谢 !
#define _parallel_qick_sort
#ifdef _parallel_qick_sort
#include <boost/shared_ptr.hpp>
#include <thread>
#include <vector>
#include <list>
#include <future>
#include <atomic>
#include "ThreadSafeStack.hpp"
using namespace std;
template<typename T>
struct sorter
{
struct chunk_to_sort
{
std::list<T> data_m;
std::promise<std::list<T> > promise_m;
};
threadsafe_stack<chunk_to_sort> chunks_m;
std::vector<std::thread> threads_m;
unsigned const max_thread_count_m;
std::atomic<bool> end_of_data_m;
sorter():
max_thread_count_m(std::thread::hardware_concurrency()-1),
end_of_data_m(false)
{}
~sorter()
{
end_of_data_m=true;
for(unsigned i=0;i<threads_m.size();++i)
{
threads_m[i].join();
}
}
void try_sort_chunk()
{
boost::shared_ptr<chunk_to_sort > chunk=chunks.pop();
if(chunk)
{
sort_chunk(chunk);
}
}
std::list<T> do_sort(std::list<T>& chunk_data)
{
if(chunk_data.empty())
{
return chunk_data;
}
std::list<T> result;
result.splice(result.begin(),chunk_data,chunk_data.begin());
T const& partition_val=*result.begin();
typename std::list<T>::iterator divide_point = std::partition(chunk_data.begin(),chunk_data.end(),[&](T const& val){return val<partition_val;});
chunk_to_sort new_lower_chunk;
new_lower_chunk.data_m.splice(new_lower_chunk.data_m.end(),chunk_data,chunk_data.begin(),divide_point);
std::future<std::list<T> > new_lower = new_lower_chunk.promise_m.get_future();
chunks_m.push(std::move(new_lower_chunk));
if(threads_m.size()<max_thread_count_m)
{
threads_m.push_back(std::thread(&sorter<T>::sort_thread,this));
}
std::list<T> new_higher(do_sort(chunk_data));
result.splice(result.end(),new_higher);
while(new_lower.wait_for(std::chrono::seconds(0)) !=
std::future_status::ready)
{
try_sort_chunk();
}
result.splice(result.begin(),new_lower.get());
return result;
}
void sort_chunk(boost::shared_ptr<chunk_to_sort > const& chunk)
{
chunk->promise_m.set_value(do_sort(chunk->data));
}
void sort_thread()
{
while(!end_of_data)
{
try_sort_chunk();
std::this_thread::yield();
}
}
};
template<typename T>
std::list<T> parallel_quick_sort(std::list<T> input)
{
if(input.empty())
{
return input;
}
sorter<T> s;
return s.do_sort(input);
}
int main()
{
list<int> l;
l.push_back(4);
l.push_back(3);
l.push_back(1);
l.push_back(2);
parallel_quick_sort(l);
return 0;
}
#endif
下面是 threadsafe_stack 类:
#ifndef __ThreadSafeStack_hpp__
#define __ThreadSafeStack_hpp__
#include "stdafx.h"
#include <exception>
#include <memory>
#include <mutex>
#include <stack>
#include <thread>
#include <iostream>
#include <functional>
#include <future>
using namespace std;
struct empty_stack : std::exception
{
const char* what() const throw()
{
return "empty stack";
}
};
template <typename T>
class threadsafe_stack
{
std::stack<T> data_m;
mutable std::mutex mutex_m;
threadsafe_stack& operator = (const threadsafe_stack&);
public:
typedef void (threadsafe_stack<T>:: * ext_push) (T);
typedef shared_ptr<T> (threadsafe_stack<T>:: *ext_pop)();
typedef void (threadsafe_stack<T>:: *ext_pop_void)(T& );
typedef bool (threadsafe_stack<T>:: *ext_empty) () const;
threadsafe_stack()
{
int i=0;
}
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(other.mutex_m);
for(int i=0; i<3; ++i)
cout << "threadsafe_stack ctor "<< i << endl;
data_m = other.data_m;
}
void push(T new_value)
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "push "<< i << endl;
data_m.push(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "pop "<< i << endl;
if(data_m.empty())
throw empty_stack();
std::shared_ptr<T> const res(std::make_shared<T>(data_m.top()));
data_m.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "pop "<< i << endl;
if(data_m.empty())
throw empty_stack();
value = data_m.top();
data_m.pop();
}
bool empty() const
{
//std::lock_guard<std::mutex> lock(mutex_m);
for(int i=0; i<3; ++i)
cout << "empty "<< i << endl;
return data_m.empty();
}
};
#endif __ThreadSafeStack_hpp__