2

If I want to get the result from a thread, which of the following code is correct? Or there exists better way to achieve the same goal?

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();
}

And another case,

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;
}
4

3 回答 3

2

在 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';
}
于 2013-09-13T04:54:41.397 回答
2

有很多方法。

请参阅http://en.cppreference.com/w/cpp/thread/future底部的示例代码

于 2013-09-13T04:44:38.653 回答
1

第二种更简单,更好,更安全。

对于第一个,您bar在两个线程之间共享一个对象 。为了安全地使用结果对象,您显然需要强制执行某种形式的同步或策略。

第一个问题的另一个问题是引用的结果对象的生命周期与原始对象的生命周期相关联,在您的情况下,原始对象位于启动线程中。如果被引用对象离开范围而工作线程仍未完成其工作并且仍未写入结果对象,这可能非常不安全。

第二个要好得多,因为它解决了上述两个问题。您还可以在任何返回其结果的函数上使用它,而该函数不知道它正在同时执行。当然,您仍然需要注意不要在共享数据时引入数据竞争和未定义的行为,尤其是在使用全局变量时。


老实说,我认为你的第二个例子有点做作。您通常不想使用单独的线程来完成这样一个微不足道的任务。这样一来,您就将自己暴露在数据竞赛中。即使您确实同步了它们的访问,启动线程和同步的开销也会使其相对于单线程代码处于严重劣势。

于 2013-09-13T04:51:39.557 回答