我写了一个非常简单的代码来重现我的问题。
#include <iostream>
#include "tools.h" //contains s_sleep()
#include <thread>
using namespace std;
void change( int *i)
{
while (true)
{
*i = 4356;
}
}
int main()
{
int v=3;
cout << v <<endl;
thread t(change, &v);
s_sleep(1); //sleep one second
cout << v << endl;
t.join();
}
输出为3,再过3秒后输出。但是当我将一行更改为
时//while ( true )
我收到3,后来又收到4356。
怎么会这样? 希望有人可以提供帮助。
答案 0 :(得分:2)
请指定您正在使用的编译器。我使用的是Microsoft Visual C ++编译器,在我的visual studio中,我看到两次输出都是3,然后是4356。
以下是我在计算机上运行的代码。
#include <ctime>
#include <thread>
#include <iostream>
using namespace std;
void change(int *i) {
while (true) { // commented out this later, the result is same.
*i = 4356;
}
}
int main() {
clock_t tstart = clock();
int v = 3;
cout << v << endl;
thread t(change, &v);
while(double(clock() - tstart)/CLOCKS_PER_SEC < 3.0) { // Instead of your s_sleep
int x = 1; // Just a dummy instruction
}
cout << v << endl;
t.join();
return 0;
}
对我的结果的解释是线程&#34; t&#34;对变量&#34; v&#34;一无所知。它只获取int类型的指针,并将指针位置的值直接编辑到内存中。所以,当主(第一)线程 再次访问变量&#34; v&#34;,它只是读取分配给&#34; v&#34;的内存。并打印它得到的东西。
而且,&#34; tools.h&#34;中的代码是什么?它与变量&#34; v&#34;有什么关系。
如果它没有,那么它必须是编译器差异(你的编译器可能与我的不同,可能是gcc或g ++?)。这意味着,您的编译器必须具有缓存(或类似的东西)变量才能更快地访问。并且在当前线程中,变量未被更改,无论何时访问它,编译器都会给出变量的旧值(编译器认为未更改)。 (我不确定这个)
答案 1 :(得分:-1)
这也可能是由于缓存造成的。您首先在一个线程中读取变量,然后从另一个线程中操作变量并从第一个线程再次读取它。编译器无法知道它在此期间发生了变化。 为了安全地做到这一点&#34; v&#34;必须声明 volatile 。