zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    jquery插件课程2 放大镜、多文件上传和在线编辑器插件如何使用
    php课程 5-19 php数据结构函数和常用函数有哪些
    如何解决计算机显示文字乱码
    NSURLConnection使用
    UOJ #5. 【NOI2014】动物园 扩大KMP
    [ACM] n划分数m部分,它要求每一个部分,并采取了最大的产品(间隔DP)
    基于低压电力采集平台DW710C的基础开发
    eclipse 对齐行号在括号中显示和字体调整
    蜗牛—苍茫IT文章大学的路(十)
    国产与第三方库FFmpeg SDK
  • 原文地址:https://www.cnblogs.com/sdk123/p/7076036.html
Copyright © 2011-2022 走看看