[英]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.