如果我想从线程中获取结果,那么以下哪个代码是正确的?还是存在更好的方法来实现相同的目标?
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;
}
第二个是更简单,更好和更安全的。
在第一个bar
线程中,您将在两个线程之间共享一个对象。您显然需要强制执行某种形式的同步或策略,以安全地使用结果对象。
第一个问题是引用的结果对象的生存期与原始对象的生存期有关,在您的情况下,原始对象的生存期在启动线程中。如果所引用的对象超出范围,而工作线程仍未完成其工作,并且仍未写入结果对象,则这可能是非常不安全的。
第二个要好得多,因为它可以解决上述两个问题。您也可以在任何返回其结果的函数上使用它,而无需知道该函数正在同时执行。当然,在共享数据时,尤其是与全局变量共享时,您仍然需要注意不要引入数据争用和未定义的行为。
老实说,我认为您的第二个例子有些人为。通常,您不想在执行此类琐碎任务时使用单独的线程。这样,您就使自己陷入了数据竞争。即使您确实同步了他们的访问,启动线程和同步的开销也会使它相对于单线程代码处于严重的劣势。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句