015 volatile关键字 线程函数的lParam 原子操作和旋转锁.

  ● 对全局变量进行 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;
}

原文地址:https://www.cnblogs.com/sdk123/p/7088029.html