ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ 多线程同步之临界区(CriticalSection)

2021-09-22 15:37:16  阅读:201  来源: 互联网

标签:include mutexattr C++ 互斥 临界 pthread CMyCriticalSection 多线程 CriticalSection


一、Win32平台

1、相关头文件和接口

1 #include <windows.h>
2 
3 CRITICAL_SECTION cs;//定义临界区对象
4 InitializeCriticalSection(&cs);//初始化临界区
5 EnterCriticalSection(&cs);//进入临界区
6 LeaveCriticalSection(&cs);//离开临界区
7 DeleteCriticalSection(&cs);//删除临界区

2、Win32源码

 1 //=====================MyCriticalSection.h===========================
 2 #ifndef _My_CRITICAL_SECTION_H
 3 #define _My_CRITICAL_SECTION_H
 4 
 5 #include <windows.h>
 6 //对临界区同样进行封装
 7 class CMyCriticalSection
 8 {
 9 public:
10     CMyCriticalSection()
11     {
12         InitializeCriticalSection(&m_cSection);
13     }
14 
15     void Lock()
16     {
17         EnterCriticalSection(&m_cSection);
18     }
19 
20     void UnLock()
21     {
22         LeaveCriticalSection(&m_cSection);
23     }
24 
25 
26     //利用析构函数删除临界区对象
27     virtual ~CMyCriticalSection()
28     {
29         DeleteCriticalSection(&m_cSection);
30     }
31 private:
32     CRITICAL_SECTION                        m_cSection;
33 };
34 
35 class CCriticalSectionAutoLock
36 {
37 public:
38     //利用构造函数上锁,即进去临界区
39     CCriticalSectionAutoLock(CMyCriticalSection *mySection)
40     :pCMySection(mySection)
41     {
42         pCMySection->Lock();
43     }
44 
45     //利用析构函数解锁,即离开临界区
46     virtual ~CCriticalSectionAutoLock()
47     {
48         pCMySection->UnLock();
49     }
50 private:
51     CMyCriticalSection                      *pCMySection;
52 };
53 
54 #endif
 1 #include <iostream>
 2 #include <windows.h>
 3 #include "MySemaphore.h"
 4 #include "MyMutex.h"
 5 #include "MyCriticalSection.h"
 6 using namespace std;
 7 
 8 //HANDLE g_hSemaphore = NULL;
 9 //HANDLE g_hMutex = NULL;
10 
11 CMySemaphore                    MySemaphore;            //信号量
12 CMyMutex                        MyMutex;                //互斥量
13 CMyCriticalSection              MyCriticalSection;      //临界区
14 
15 DWORD WINAPI Fun(LPVOID lpParamter)
16 {
17     string strPrint((const char*)lpParamter);
18     int iRunTime = 0;
19     //执行100次跳出
20     while(++iRunTime<10)
21     {
22         {
23             CCriticalSectionAutoLock  cLock(&MyCriticalSection);
24             cout <<"["<< iRunTime <<"]:"<< strPrint.c_str()<<endl;
25         }
26         Sleep(1); //若去掉此句 可能导致其他线程无法进入临界区,因为 cLock在这之前析构,离开临界区
27 
28     }
29     return 0;
30 }
31 
32 int main()
33 {
34     //创建五个子线程
35     string str1 = "A";
36     string str2 = "B";
37     string str3 = "C";
38     string str4 = "D";
39     string str5 = "E";
40 
41     HANDLE hThread1 = CreateThread(NULL, 0, Fun, (void*)str1.c_str(), 0, NULL);
42     HANDLE hThread2 = CreateThread(NULL, 0, Fun, (void*)str2.c_str(), 0, NULL);
43     HANDLE hThread3 = CreateThread(NULL, 0, Fun, (void*)str3.c_str(), 0, NULL);
44     HANDLE hThread4 = CreateThread(NULL, 0, Fun, (void*)str4.c_str(), 0, NULL);
45     HANDLE hThread5 = CreateThread(NULL, 0, Fun, (void*)str5.c_str(), 0, NULL);
46 
47     //关闭线程
48     CloseHandle(hThread1);
49     CloseHandle(hThread2);
50     CloseHandle(hThread3);
51     CloseHandle(hThread4);
52     CloseHandle(hThread5);
53 
54     getchar();
55 //  system("pause");
56     return 0;
57 }

执行结果:
这是加上Sleep(1);的运行结果,没有加上Sleep(1);的执行结果如下:

从结果我们可以看出如果没有加上Sleep(1),即在离开临界区后进行休眠,其他线程进入临界区的概率会大大降低,原因可能是由于While循环在不停的循环时,其他线程还没有那么快能够进入临界区,因此在这种情况下想让所有的线程都有机会进入临界区,则需要在离开临界区之后做短暂休眠即可。

3、Linux平台
在Linux环境下,没有Windows下的临界区的概念,但是也可以利用互斥量实现该功能。Linux下的API如下,在前面的博文里也有讲到过

1 #include <pthread.h>
2 int pthread_mutexattr_init(pthread_mutexattr_t *attr); /*初始化函数*/
3 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);/*去初始化函数*/
4 
5 int pthread_mutex_lock(pthread_mutexattr_t *attr)/*加锁*/
6 int pthread_mutex_unlock(pthread_mutexattr_t *attr)/*解锁*/

但是两者并不是完全一样的,他们的区别总结如下:
1、临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。
2、临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。
3、临界区和互斥体在Windows平台都下可用;Linux下只有互斥体可用。
4、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
5、互斥量:为协调共同对一个共享资源的单独访问而设计的。

标签:include,mutexattr,C++,互斥,临界,pthread,CMyCriticalSection,多线程,CriticalSection
来源: https://www.cnblogs.com/ybqjymy/p/15320059.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有