zoukankan      html  css  js  c++  java
  • window下线程同步之(Critical Sections(关键代码段、关键区域、临界区域)----转载

    转载:https://www.cnblogs.com/cyblogs/p/9948379.html

     

     关键区域(CriticalSection)

    临界区是为了确保同一个代码片段在同一时间只能被一个线程访问,与原子锁不同的是临界区是多条指令的锁定,而原子锁仅仅对单条操作指令有效;临界区和原子锁只能控制同一个进程中线程的同步

    使用方法:

    1、初始化:InitializeCriticalSection; 
    2、删除:DeleteCriticalSection; 
    3、进入:EnterCriticalSection(可能造成阻塞); 
    4、尝试进入:TryEnterCriticalSection(不会造成阻塞); 
    5、离开:LeaveCriticalSection;

    固有特点(优点+缺点): 
    1、是一个用户模式的对象,不是系统核心对象; 
    2、因为不是核心对象,所以执行速度快,有效率; 
    3、因为不是核心对象,所以不能跨进程使用; 
    4、可以多次“进入”,但必须多次“退出”; 
    5、最好不要同时进入或等待多个 Critical Sections,容易造成死锁; 
    6、无法检测到进入到 Critical Sections 里面的线程当前是否已经退出!

    一般错误的情况:

    复制代码
    #include <stdio.h> 
    #include <windows.h>
    
    long g_nNum = 0 ; 
    DWORD WINAPI ThreadProc(__in  LPVOID lpParameter); 
    const int THREAD_NUM = 10;
    
    int main() 
    {
    
        HANDLE  handle[THREAD_NUM];    
        g_nNum = 0; 
        int var = 0; 
        while ( var< THREAD_NUM) 
        { 
            handle[ var++] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    
        } 
        WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
    
        for( var=0; var<sizeof(handle); var++) 
        { 
            CloseHandle(handle[var]); 
        }
    
        return 0; 
    }
    
    DWORD WINAPI ThreadProc(__in  LPVOID lpParameter) 
    { 
        Sleep(50); 
        g_nNum++; 
        Sleep(0); 
        printf("当前计数为:%d
    ",g_nNum); 
        return 0; 
    }
    复制代码

    运行2次结果:

    image

    image

    用了关键区域的情况:

    复制代码
    #include <stdio.h> 
    #include <windows.h>
    
    long g_nNum = 0 ; 
    DWORD WINAPI ThreadProc(__in  LPVOID lpParameter); 
    const int THREAD_NUM = 10;
    
    CRITICAL_SECTION g_ThreadCode;
    
    int main() 
    {
    
        HANDLE  handle[THREAD_NUM];    
        g_nNum = 0; 
        int var = 0; 
        InitializeCriticalSection(&g_ThreadCode); 
        while ( var< THREAD_NUM) 
        { 
            handle[ var++] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); 
        } 
        WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); 
        DeleteCriticalSection( &g_ThreadCode ); 
        
        for( var=0; var<sizeof(handle); var++) 
        { 
            CloseHandle(handle[var]); 
        }
    
        return 0; 
    }
    
    DWORD WINAPI ThreadProc(__in  LPVOID lpParameter) 
    {  
        EnterCriticalSection( &g_ThreadCode ); 
        g_nNum++;  
        printf("当前计数为:%d
    ",g_nNum); 
        LeaveCriticalSection( &g_ThreadCode ); 
        return 0; 
    }
    复制代码
  • 相关阅读:
    联想 Vibe Shot(Z90-3) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625
    联想 Z5S(L78071)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.370
    联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
    联想 S5 Pro(L78041)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 5.0.123
    第二阶段 冲刺八
    第二阶段 冲刺七
    第二阶段 冲刺六
    第二阶段 冲刺五
    代码大全阅读笔记03
    学习进度十二
  • 原文地址:https://www.cnblogs.com/cyblogs/p/9948471.html
Copyright © 2011-2022 走看看