• 线程的临界区


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

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

    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
  • 相关阅读:
    Spring Boot整合Spring Data Jpa + QueryDSL
    jeecgboot-3.5.5本地安装部署
    如何两个不同的脚本文件之间传递参数
    linux新建账号并配置权限
    flutter监听键盘输入做出反应
    STM32 裸机编程 03
    后端——缓存Cookie、缓存Session、cookies和Session的区别:
    2021年上半年软件设计师下午真题及答案解析(三)
    python日期计算器 青少年编程电子学会python编程等级考试二级真题解析2021年12月
    2021 Adversarial Attack(李宏毅
  • 原文地址:https://blog.csdn.net/weixin_44309282/article/details/126873176