问题是我有一个函数可以计算并获得这些操作的结果。获得结果后,我想比较并使用标准获得最佳结果。问题是我不知道将变量与线程得到的结果进行比较是否是个好主意。例如,如果两个线程同时与这个变量进行比较,或者它有某种防御,那会不会搞砸事情呢?
#include <iostream>
#include <thread>
double RESULT;
void call_from_thread(int i)
{
//some calculation
double result;
if(result>RESULT)
{
RESULT=result;
}
}
int main(int argc, char *argv[])
{
std::thread t[64];
for(int i=0;i<64;i++)
{
t[i]=std::thread(call_from_thread,i);
}
for(int i=0;i<64;i++)
{
t[i].join();
}
return 0;
}
是否会导致结果混乱? 除了定义64个更多变量之外的任何想法或这是唯一的方法吗?
答案 0 :(得分:0)
我建议您使用asyncs,并在主线程中进行所有比较。在这种情况下,您不需要任何同步。即:
#include <future>
#include <vector>
#include <iostream>
double foo(int i) {
// Do the compuation and return result like this
return static_cast<double>(i);
}
int main(int argc, char *argv[])
{
double RESULT;
std::vector<std::future<double>> asyncs;
for(int i = 0; i < 64; ++i)
asyncs.emplace_back(std::async(std::launch::async,
foo, i));
for(auto & future : asyncs) {
double result = future.get();
if(result > RESULT)
RESULT = result;
}
std::cout << RESULT << std::endl;
}
在其他情况下,您需要创建全局std::mutex
并在每次设置结果时使用std :: lock_quard获取它。即:
std::mutex mtx;
...
void add_result(double result) {
std::lock_quard<std::mutex> lock(mtx);
if(result > RESULT)
RESULT = result;
}
答案 1 :(得分:0)
您的代码在全局变量RESULT
上遇到竞争条件。不同的线程正在读写这个变量。不能保证这会产生正确的答案,无论是什么&#39;正确的&#39;可能意味着,多次运行相同的代码很可能会给出不同的RESULT
。
有几种方法可以应对这种竞争条件。最好的方法是将它们全部放在一起,就像在我自己的答案中一样。但是,有时他们无法避免。在这种情况下,您必须使用atomic
访问权限或保护mutex
的访问权限。对于double
的情况,mutex
可能是最佳解决方案,看起来像
std::mutex MUTEX;
double RESULT;
void call_from_thread(int i)
{
//some calculation
double result;
std::lock_guard<std::mutex> lock(MUTEX); // see documentation
if(result>RESULT)
{
RESULT=result;
}
}
重要的是你要保护同一个关键区域(在此定义为变量result>RESULT
的范围)中的读数(在RESULT=result
中)和写入(在lock
中)