Почему приведенный ниже код не может вывести Hello World!Это связано с кешем процессора?Но я думаю, что процессор должен гарантировать целостность кэша, верно?Если thread_fun обновит кеш из памяти после того, как thread_fun2 изменит значение.Я знаю, что atomic может решить эту проблему, но я не знаю, почему приведенный ниже код не работает.
#include <stdio.h>
#include <thread>
int a = 4;
void thread_fun() {
while(a!=3) {
}
printf("Hello world!\n");
}
void thread_fun2() {
a=3;
printf("Set!\n");
}
int main() {
auto tid=std::thread(thread_fun);
auto tid2=std::thread(thread_fun2);
tid.join();
tid2.join();
}
Параметры сборки:
g++ -o multi multi.cc -O3 -std=c++11 -lpthread
Ниже приведен вывод gdb
(gdb) disass thread_fun
Dump of assembler code for function _Z10thread_funv:
0x0000000000400af0 <+0>: cmpl $0x3,0x201599(%rip) # 0x602090 <a>
0x0000000000400af7 <+7>: je 0x400b00 <_Z10thread_funv+16>
0x0000000000400af9 <+9>: jmp 0x400af9 <_Z10thread_funv+9>
0x0000000000400afb <+11>: nopl 0x0(%rax,%rax,1)
0x0000000000400b00 <+16>: mov $0x401090,%edi
0x0000000000400b05 <+21>: jmpq 0x4008f0 <puts@plt>
End of assembler dump.
(gdb) disass thread_fun2
Dump of assembler code for function _Z11thread_fun2v:
0x0000000000400b10 <+0>: mov $0x40109d,%edi
0x0000000000400b15 <+5>: movl $0x3,0x201571(%rip) # 0x602090 <a>
0x0000000000400b1f <+15>: jmpq 0x4008f0 <puts@plt>
End of assembler dump.
(gdb)
Тестовый вывод
[root@centos-test tmp]# ./multi
Set!
^C
[root@centos-test tmp]# ./multi
Set!
^C
[root@centos-test tmp]# ./multi
Set!
^C
[root@centos-test tmp]# ./multi
Set!
^C
[root@centos-test tmp]# ./multi
Set!
^C
ОБНОВЛЕНИЕ: спасибо всем, теперь я обнаружил, что на самом деле эта проблема была вызвана компилятором.
(gdb) disass thread_fun
Dump of assembler code for function _Z10thread_funv:
0x0000000000400af0 <+0>: cmpl $0x3,0x201599(%rip) # 0x602090 <a>
0x0000000000400af7 <+7>: je 0x400b00 <_Z10thread_funv+16>
0x0000000000400af9 <+9>: jmp 0x400af9 <_Z10thread_funv+9> ###jump to itself
0x0000000000400afb <+11>: nopl 0x0(%rax,%rax,1)
0x0000000000400b00 <+16>: mov $0x401090,%edi
0x0000000000400b05 <+21>: jmpq 0x4008f0 <puts@plt>
End of assembler dump.
Кажется, компилятор рассматривал его какоднопоточное приложение.