簡體   English   中英

使用c ++ 11線程返回結果的正確方法是什么?

[英]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;
}

有很多方法。

請參閱http://en.cppreference.com/w/cpp/thread/future底部的示例代碼

在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM