首页 > 代码库 > 015 原子操作 旋转锁

015 原子操作 旋转锁

以下代码个别情况下会出错 导致值为1

 

#define UNICODE
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <process.h>

long gNum = 0;
unsigned int __stdcall ThreadRun1(void* lParam)
{
    ////原子操作
    //同一资源在同一时间只有一个线程能够访问
    //系统级的操作
    //在硬件里面设置了一些局限性
    InterlockedExchangeAdd(&gNum,1);
//    gNum += 1;
    return 0;
}

unsigned int __stdcall ThreadRun2(void* lParam)
{
    InterlockedExchangeAdd(&gNum,1);
    //gNum += 1;
    return 0;
}
int main()
{
    HANDLE hThread[2];
    hThread[0] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun1,nullptr,0,nullptr);
    hThread[1] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun2,hThread[0],0,nullptr);
    WaitForMultipleObjects(sizeof(hThread)/sizeof(HANDLE), hThread,TRUE, INFINITE);
    printf("gNum:%d",gNum);
    for(int i = 0; i<sizeof(hThread)/sizeof(HANDLE);++i)
    {
        CloseHandle(hThread[i]);
    }
    return 0;
}

 

#define UNICODE
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <process.h>

long gNum = 0;
unsigned int __stdcall ThreadRun1(void* lParam)
{
    ////原子操作
    //同一资源在同一时间只有一个线程能够访问
    //系统级的操作
    //在硬件里面设置了一些局限性    gNum += 1;
    return 0;
}

unsigned int __stdcall ThreadRun2(void* lParam)
{gNum += 1;
    return 0;
}
int main()
{
    HANDLE hThread[2];
    hThread[0] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun1,nullptr,0,nullptr);
    hThread[1] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun2,hThread[0],0,nullptr);
    WaitForMultipleObjects(sizeof(hThread)/sizeof(HANDLE), hThread,TRUE, INFINITE);
    printf("gNum:%d",gNum);
    for(int i = 0; i<sizeof(hThread)/sizeof(HANDLE);++i)
    {
        CloseHandle(hThread[i]);
    }
    return 0;
}

 

出错的原因

技术分享

下面是加硬件锁代码

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <tchar.h>
 4 #include <windows.h>
 5 #include <process.h>
 6 
 7 long gNum = 0;
 8 unsigned int __stdcall ThreadRun1(void* lParam)
 9 {
10     //11     //原子操作
12     //同一资源在同一时间只有一个线程能够访问
13     //系统级的操作
14     //在硬件里面设置了一些局限性
15     InterlockedExchangeAdd(&gNum,1);
16 //    gNum += 1;
17     return 0;
18 }
19 
20 unsigned int __stdcall ThreadRun2(void* lParam)
21 {
22     InterlockedExchangeAdd(&gNum,1);
23     //gNum += 1;
24     return 0;
25 }
26 int main()
27 {
28     HANDLE hThread[2];
29     hThread[0] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun1,nullptr,0,nullptr);
30     hThread[1] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun2,hThread[0],0,nullptr);
31     WaitForMultipleObjects(sizeof(hThread)/sizeof(HANDLE), hThread,TRUE, INFINITE);
32     printf("gNum:%d",gNum);
33     for(int i = 0; i<sizeof(hThread)/sizeof(HANDLE);++i)
34     {
35         CloseHandle(hThread[i]);
36     }
37     return 0;
38 }

 

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <tchar.h>
 4 #include <windows.h>
 5 #include <process.h>
 6 
 7 long gNum = 0;
 8 BOOL bUseing = FALSE;
 9 
10 //线程的饥饿
11 //线程优先级
12 //CPU
13 //调度区
14 //        1        31
15 //        2        31
16 //        3        30        饥饿 可能永远得不到执行
17 unsigned int __stdcall ThreadRun1(void* lParam)
18 {
19     //20     //原子操作
21     //同一资源在同一时间只有一个线程能够访问
22     //系统级的操作
23     //在硬件里面设置了一些局限性
24     while(InterlockedExchange((long*)&bUseing, TRUE) != TRUE)    //旋转锁
25         Sleep(0);
26         
27     //.....        上锁后的代码  线程安全 绝对安全的
28     InterlockedExchange((long*)&bUseing, FALSE);
29 //    gNum += 1;
30     return 0;
31 }
32 
33 unsigned int __stdcall ThreadRun2(void* lParam)
34 {
35     //InterlockedExchangeAdd(&gNum,1);
36     //gNum += 1;
37     while(InterlockedExchange((long*)&bUseing, TRUE) != TRUE)
38     Sleep(0);
39         
40     //.....        上锁后的代码  线程安全
41     
42     InterlockedExchange((long*)&bUseing, FALSE);
43     return 0;
44 }
45 int main()
46 {
47     HANDLE hThread[2];
48     hThread[0] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun1,nullptr,0,nullptr);
49     hThread[1] = (HANDLE)_beginthreadex(nullptr,0,ThreadRun2,hThread[0],0,nullptr);
50     WaitForMultipleObjects(sizeof(hThread)/sizeof(HANDLE), hThread,TRUE, INFINITE);
51     printf("gNum:%d",gNum);
52     for(int i = 0; i<sizeof(hThread)/sizeof(HANDLE);++i)
53     {
54         CloseHandle(hThread[i]);
55     }
56     return 0;
57 }

 

015 原子操作 旋转锁