[英]What is the correct way to return result by using c++11 thread?
如果我想從線程中獲取結果,以下哪個代碼是正確的? 還是存在更好的方法來實現相同的目標?
void foo(int &result) {
result = 123;
}
int bar() {
return 123;
}
int main() {
int foo_result;
std::thread t1(foo, std::ref(foo_result));
t1.join();
std::future<int> t2 = std::async(bar);
int bar_result = t2.get();
}
還有一種情況
void baz(int beg, int end, vector<int> &a) {
for (int idx = beg; idx != end; ++idx) a[idx] = idx;
}
int main() {
vector<int> a(30);
thread t0(baz, 0, 10, ref(a));
thread t1(baz, 10, 20, ref(a));
thread t2(baz, 20, 30, ref(a));
t0.join();
t1.join();
t2.join();
for (auto x : a) cout << x << endl;
}
有很多方法。
在C ++ 11中,您想使用std::future
從此文檔鏈接 :
類模板std :: future提供了一種機制來訪問異步操作的結果
還有一些示例代碼(也來自該鏈接)說明了其用法。
#include <iostream>
#include <future>
#include <thread>
int main()
{
// future from a packaged_task
std::packaged_task<int()> task([](){ return 7; }); // wrap the function
std::future<int> f1 = task.get_future(); // get a future
std::thread(std::move(task)).detach(); // launch on a thread
// future from an async()
std::future<int> f2 = std::async(std::launch::async, [](){ return 8; });
// future from a promise
std::promise<int> p;
std::future<int> f3 = p.get_future();
std::thread( [](std::promise<int>& p){ p.set_value(9); },
std::ref(p) ).detach();
std::cout << "Waiting..." << std::flush;
f1.wait();
f2.wait();
f3.wait();
std::cout << "Done!\nResults are: "
<< f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n';
}
第二個更簡單,更好和更安全。
在第一個線程中,您正在兩個線程之間共享對象bar
。 您顯然需要強制執行某種形式的同步或策略,以安全地使用結果對象。
第一個問題是,引用結果對象的生存期與原始對象的生存期有關,在您的情況下,原始對象的生存期在啟動線程中。 如果所引用的對象超出范圍,而工作線程仍未完成其工作,並且仍未寫入結果對象,則這可能是非常不安全的。
第二個要好得多,因為它可以解決上述兩個問題。 您也可以在返回結果的任何函數上使用它,而無需知道該函數正在同時執行。 當然,在共享數據時,尤其是與全局變量共享時,您仍然需要注意不要引入數據競爭和未定義的行為。
老實說,我認為您的第二個例子有些人為。 通常,您不想在執行此類瑣碎任務時使用單獨的線程。 這樣,您就使自己陷入了數據競爭。 即使您同步了他們的訪問,啟動線程和同步的開銷也會使它相對於單線程代碼處於嚴重的劣勢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.