● 对全局变量进行 volatile 可以阻止编译器对变量的优化
● lparam 线程函数的传参 1 #include <windows.h>
2 #include <stdio.h> 3 #include <tchar.h> 4 #include <process.h> 5 6 int gNum = 0; 7 const int LOOPCOUNT = 1000; 8 const int THREADCONUT = 1000; 9 10 unsigned __stdcall ThreadFun(void *lParam) 11 { 12 int nThreadNo = (int)lParam; 13 gNum = 0; 14 for( int i = 0; i < LOOPCOUNT; ++i) 15 { 16 gNum += i; 17 } 18 printf("Threaad%4d:gNum=gNum=%d ",nThreadNo,gNum); 19 return 0; 20 } 21 int main() 22 { 23 HANDLE hThreads[THREADCONUT] = {0}; 24 for(int i=0; i<THREADCONUT; ++i) 25 { 26 hThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFun, (void*)i, 0, nullptr); 27 } 28 WaitForMultipleObjects(THREADCONUT, hThreads, TRUE, INFINITE); 29 30 for(int i = 0; i< THREADCONUT; ++i) 31 { 32 CloseHandle(hThreads[i]); 33 } 34 return 0; 35 }
● (void*)i, 临时变量i 强制转换位 void* 然后在 线程函数内 再转换回int
● 另外一种传参的方法
1 #include <windows.h> 2 #include <stdio.h> 3 #include <tchar.h> 4 #include <process.h> 5 6 int gNum = 0; 7 const int LOOPCOUNT = 1000; 8 const int THREADCONUT = 1000; 9 10 unsigned __stdcall ThreadFun(void *lParam) 11 { 12 int *nThreadNo = (int*)lParam; 13 gNum = 0; 14 for( int i = 0; i < LOOPCOUNT; ++i) 15 { 16 gNum += i; 17 } 18 printf("Threaad%4d:gNum=gNum=%d ",*nThreadNo,gNum); 19 return 0; 20 } 21 int main() 22 { 23 HANDLE hThreads[THREADCONUT] = {0}; 24 for(int i=0; i<THREADCONUT; ++i) 25 { 26 hThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFun, &i, 0, nullptr); 27 } 28 WaitForMultipleObjects(THREADCONUT, hThreads, TRUE, INFINITE); 29 30 for(int i = 0; i< THREADCONUT; ++i) 31 { 32 CloseHandle(hThreads[i]); 33 } 34 return 0; 35 }
● 执行结果黑诡异
● 线程是同时执行的不分先后顺序
● 原子操作
1 #include <windows.h> 2 #include <stdio.h> 3 #include <tchar.h> 4 #include <process.h> 5 6 volatile int gNum = 0; 7 const int LOOPCOUNT = 1000; 8 const int THREADCONUT = 1000; 9 10 unsigned __stdcall ThreadFun(void *lParam) 11 { 12 int nThreadNo = (int)lParam; 13 gNum = 0; 14 for( int i = 0; i < LOOPCOUNT; ++i) 15 { 16 //gNum += i; 17 InterlockedExchangeAdd((long*)&gNum,i); 18 } 19 printf("Threaad%4d:gNum=gNum=%d ",nThreadNo,gNum); 20 return 0; 21 } 22 int main() 23 { 24 HANDLE hThreads[THREADCONUT] = {0}; 25 for(int i=0; i<THREADCONUT; ++i) 26 { 27 hThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFun, (void*)i, 0, nullptr); 28 } 29 WaitForMultipleObjects(THREADCONUT, hThreads, TRUE, INFINITE); 30 31 for(int i = 0; i< THREADCONUT; ++i) 32 { 33 CloseHandle(hThreads[i]); 34 } 35 return 0; 36 }
● 反而错误更多了
#include <windows.h> #include <stdio.h> #include <tchar.h> #include <process.h> volatile int gNum = 0; volatile BOOL gbUseing = FALSE; const int LOOPCOUNT = 1000; const int THREADCONUT = 1000; unsigned __stdcall ThreadFun(void *lParam) { int nThreadNo = (int)lParam; //gNum += i; while(InterlockedExchangeAdd((long*)&gbUseing,TRUE)==TRUE) { Sleep(0); } printf("Entry Thread%4d ",nThreadNo); gNum = 0; printf("Threaad%4d:gNum=gNum=%d ",nThreadNo,gNum); InterlockedExchangeAdd((long*)&gbUseing,FALSE); return 0; } int main() { HANDLE hThreads[THREADCONUT] = {0}; for(int i=0; i<THREADCONUT; ++i) { hThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFun, (void*)i, 0, nullptr); } WaitForMultipleObjects(THREADCONUT, hThreads, TRUE, INFINITE); for(int i = 0; i< THREADCONUT; ++i) { CloseHandle(hThreads[i]); } return 0; }