zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    RT-Thread can
    scons自动化构建工具
    Android 数据库 SQLiteOpenHelper
    请确保二进制储存在指定的路径中,或者调试他以检查该二进制或相关的DLL文件
    攻防世界misc新手区前三题
    基于session对象实现简单的购物车应用
    MS Excel中的内部日期处理方法
    如何实现对指定日期进行增减日期操作结果的输出
    2020前端大厂最新面试题,这一波我是用“身子换来的”
    字节、拼多多前端面经!
  • 原文地址:https://www.cnblogs.com/sdk123/p/7088029.html
Copyright © 2011-2022 走看看