多線程的坑--volatile
阿新 • • 發佈:2018-03-19
多線程 volatile 多線程編程中 開優化選項時要謹慎否則容易掉坑裏
先看下面的代碼,開起兩個線程,第二個線程把第一個線程的循環條件置成false 按邏輯來說這個應該能順利結束的不過如果用
g++ -O3 -o multiThread multiThread.cpp -lpthread
編譯的話TestThread1是退不出來的,只有 g_brun 加上 volatile關鍵字才能正常退出
因為在-O3優化選項下 執行TestThread1時g_brun會先讀到寄存器中,編譯器發現這個函數中g_brun沒有任何改變所以不會再去內存中取值直接用寄存器中的備份,在TestThread2中改變了g_brun在內存中的值,對TestThread1中g_brun的寄存器備份沒有任何影響。
加上volatile表示對該變量不優化每次都去內存中取值。
先看下面的代碼,開起兩個線程,第二個線程把第一個線程的循環條件置成false 按邏輯來說這個應該能順利結束的不過如果用
g++ -O3 -o multiThread multiThread.cpp -lpthread
編譯的話TestThread1是退不出來的,只有 g_brun 加上 volatile關鍵字才能正常退出
因為在-O3優化選項下 執行TestThread1時g_brun會先讀到寄存器中,編譯器發現這個函數中g_brun沒有任何改變所以不會再去內存中取值直接用寄存器中的備份,在TestThread2中改變了g_brun在內存中的值,對TestThread1中g_brun的寄存器備份沒有任何影響。
#include <pthread.h> #include <iostream> #include <unistd.h> using namespace std; //volatile bool g_brun = true; bool g_brun = true; void* TestThread1(void* arg) { cout << "TestThread1 進入" << endl; long long ll = 0; while(g_brun) ll ++; cout << "TestThread1 退出 ll:" << ll << endl; } void* TestThread2(void* arg) { cout << "TestThread2 進入" << endl; g_brun = false; cout << "TestThread2 退出 設置 g_brun = false" << endl; } int main() { pthread_t threadId1; pthread_create(&threadId1, NULL, TestThread1, NULL); usleep(1000000); // 保證TestThread1先執行 pthread_t threadId2; pthread_create(&threadId2, NULL, TestThread2, NULL); pthread_join(threadId1,NULL); pthread_join(threadId2,NULL); return 0; }
多線程的坑--volatile