• 线程的临界区


    临界区解决线程冲突问题,多个线程操作同一个变量,会引发这样对待问题。

    注意:不要让多个程序同时访问一个变量,如果要访问,急用临界区来操作,或让他们每个时间段每个时间段来访问。

    1.下面的程序中,得到的正确结果应该是200000,但是它实际上得到的结果极其不稳定,同时运行每一个线程,可能会有几个就漏掉了,最后得到的结果也就不稳定了

    #include 
    #include 
    #include 
    #define N 20
    
    int num = 0;
    DWORD WINAPI add(void *p)
    {
        for (int i = 0; i < 10000, i++)
        {
            num++;
        }
    }
    
    int main()
    {
        
        HANDLE hd[N];
        for (int i = 0; i < N; i++)
        {
            hd[i] = CreatThread(NULL, 0, add, NULL, 0, NULL);
        }
        WaitForMultipleObjects(N, hd, TRUE, INFINITE);	//等待全部退出
        pirntf("num-%d", num);
        system("pause");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.要想让他正确有两种方法
    法一:

    #include 
    #include 
    #include 
    #define N 20
    
    int num = 0;
    DWORD WINAPI add(void *p)
    {
        for (int i = 0; i < 10000, i++)
        {
            num++;
        }
    }
    
    int main()
    {
        
        HANDLE hd[N];
        for (int i = 0; i < N; i++)
        {
            hd[i] = CreatThread( NULL, 0, add, NULL, 0, NULL);     
            WaitForSingleObject(hd[i], INFINITE);  //加入的这一行后,  
            //进程是一个一个进行的,不会出错,但是如果单个进程时间长,最后花费的时间会很长。 
        }
        WaitForMultipleObjects(N, hd, TRUE, INFINITE);	//等待全部退出
        pirntf("num-%d", num);
        system("pause");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    法二:

    #include 
    #include 
    #include 
    #define N 20
    
    int num = 0;
    CRITICAL_SECTION cs1
    CRITICAL_SECTION cs2;  //定义临界区,其实质是一个结构体变量,
    						//当访问cs的时候其他线程都是锁定的,至少处于一个等待状态。
    DWORD WINAPI add(void *p)
    {   
    	EnterCriticalSection(&cs1);		//进入临界区
        for (int i = 0; i < 10000, i++)
        {     
            num++;  
        }  
        LeaveCriticalSection(&cs1);		//离开临界区
    }
    int main() {    
     	 InitializeCriticalSection(&cs1);  //初始化 ,C++会自动初始化   
     	 HANDLE hd[N];    
     	 for (int i = 0; i < N; i++)   
     	 { 
     	       hd[i] = CreatThread(NULL, 0, add, NULL, 0, NULL);    
     	 }   
     	 WaitForMultipleObjects(N, hd, TRUE, INFINITE);		//等待全部退出    
     	 pirntf("num-%d", num);   
     	 DeleteCriticalSection(&cs1);  //释放,由于该结构体中有指针,这个指针会在堆上开辟内存
       	 system("pause");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    系统安全分析与设计
    【Python脚本进阶】2.1、端口扫描器(上):TCP全连接扫描
    二、sql手工注入
    全国流通经济杂志全国流通经济杂志社全国流通经济编辑部2022年第25期目录
    Android按下录音录音动画效果 ,自定义录音、播放动画View
    关于这个“微信提现”的问题,太炸裂了,以至于我写了段代码来验证!
    Material ShapeableImageView 使用详解
    深入剖析多重背包问题(上篇)
    阿里云消息团队创新论文被软件工程顶会 FM 2024 录用
    Shapiro-Wilk正态性检验(Shapiro和Wilk于1965年提出)
  • 原文地址:https://blog.csdn.net/weixin_44309282/article/details/126873176