[英]Error about std::promise in C++
我试图将我的类实例传递给线程,并从线程返回处理后的对象。 我搜索了C ++多线程,发现std :: promising可能会有所帮助。
但是,我一开始就陷入困境。 这是我的代码:
void callerFunc()
{
//...
std::promise<DataWareHouse> data_chunks;
// DataWareHouse is my customized class
//data_chunks has a vector<vector<double>> member variable
std::thread(&run_thread,data_chunks);
// ............
}
void run_thread(std::promise<DataWareHouse> data_chunks)
{
// ...
vector<vector<double>> results;
// ...
data_chunks.set_value(results);
}
上面的代码生成错误:
`error C2248: 'std::promise<_Ty>::promise' : cannot access private member declared in class 'std::promise<_Ty>'`
我可以知道我在做什么以及如何解决吗?
非常感谢。 :-)
您的第一个问题是您正在使用std::thread
- std::thread
是一个低级类,应在其上构建更高的抽象。 线程在C ++ 11中的C ++中是新标准化的,并且所有粗略部分都尚未提出。
在C ++ 11中使用线程的三种不同模式可能对您有用。
首先, std::async
。 其次, std::thread
与std::packaged_task
混合。 第三,处理原始的std::thread
和std::promise
。
我将说明第三个级别,它是最低级别和最危险的级别,因为这是您所要求的。 我建议您看一下前两个选项。
#include <future>
#include <vector>
#include <iostream>
typedef std::vector<double> DataWareHouse;
void run_thread(std::promise<DataWareHouse> data_chunks)
{
DataWareHouse results;
results.push_back( 3.14159 );
data_chunks.set_value(results);
}
std::future<DataWareHouse> do_async_work()
{
std::promise<DataWareHouse> data_chunks;
std::future<DataWareHouse> retval = data_chunks.get_future();
// DataWareHouse is my customized class
//data_chunks has a vector<vector<double>> member variable
std::thread t = std::thread(&run_thread,std::move(data_chunks));
t.detach(); // do this or seg fault
return retval;
}
int main() {
std::future<DataWareHouse> result = do_async_work();
DataWareHouse vec = result.get(); // block and get the data
for (double d: vec) {
std::cout << d << "\n";
}
}
使用std::async
,您将具有一个返回DataWareHouse
的函数,它将直接返回std::future<DataWareHouse>
。
使用std::packaged_task<>
,它将占用您的run_thread
并将其转换为可以执行的packaged_task
,并从中提取std::future
。
std::promise<>
是不可复制的,并且在调用run_thread()
您隐式地尝试调用复制构造函数。 该错误消息告诉您,由于标记为私有,因此无法使用复制构造函数。
您需要通过引用传递一个承诺( std::promise<DataWareHouse> &
)。 如果这是安全的callerFunc()
保证不会返回,直到run_thread()
完成与对象(否则你将使用到销毁堆栈分配对象的引用,而我也没有解释为什么这是很糟糕)。
您正在尝试通过值将承诺传递给线程; 但是您需要通过引用传递结果,以将结果返回给呼叫者的承诺。 std::promise
无法复制,以防止发生此错误。
std::thread(&run_thread,std::ref(data_chunks));
^^^^^^^^
void run_thread(std::promise<DataWareHouse> & data_chunks)
^
错误提示您无法复制std::promise
,您可以在此处执行以下操作:
void run_thread(std::promise<DataWareHouse> data_chunks)
和这里:
std::thread(&run_thread,data_chunks); // makes copy of data_chunks
您应该传递参考:
void run_thread(std::promise<DataWareHouse>& data_chunks);
// ^
然后将std::reference_wrapper
传递给线程,否则它也会尝试复制promise。 这可以通过std::ref
轻松完成:
std::thread(&run_thread, std::ref(data_chunks));
// ^^^^^^^^
显然,在线程完成运行之前, data_chunks
必须处于活动状态,因此您必须在callerFunc()
加入线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.