• 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;
    }

  • 相关阅读:
    Spring配置文件的命名空间URI
    Hibernate @Embeddable注释
    HIbernate实体类注解配置
    Hibernate关系映射之many-to-many
    Hibernate中cascade属性的区别
    Hibernate注解配置与XML配置区别
    JPA关系映射之one-to-one
    Mysql修改id自增值
    JPA关系映射之one-to-many和many-to-one
    swift
  • 原文地址:https://www.cnblogs.com/sdk123/p/7088029.html
Copyright © 2020-2023  润新知