C++多线程同步之临界区(CriticalSection)
原文链接:http://blog.csdn.net/olansefengye1/article/details/53262917
一、Win32平台
1、相关头文件和接口
#include <windows.h>
CRITICAL_SECTION cs;//定义临界区对象
InitializeCriticalSection(&cs);//初始化临界区
EnterCriticalSection(&cs);//进入临界区
LeaveCriticalSection(&cs);//离开临界区
DeleteCriticalSection(&cs);//删除临界区
2、Win32源码
//=====================MyCriticalSection.h===========================
#ifndef _My_CRITICAL_SECTION_H
#define _My_CRITICAL_SECTION_H
#include <windows.h>
//对临界区同样进行封装
class CMyCriticalSection
{
public:
CMyCriticalSection()
{
InitializeCriticalSection(&m_cSection);
}
void Lock()
{
EnterCriticalSection(&m_cSection);
}
void UnLock()
{
LeaveCriticalSection(&m_cSection);
}
//利用析构函数删除临界区对象
virtual ~CMyCriticalSection()
{
DeleteCriticalSection(&m_cSection);
}
private:
CRITICAL_SECTION m_cSection;
};
class CCriticalSectionAutoLock
{
public:
//利用构造函数上锁,即进去临界区
CCriticalSectionAutoLock(CMyCriticalSection *mySection)
:pCMySection(mySection)
{
pCMySection->Lock();
}
//利用析构函数解锁,即离开临界区
virtual ~CCriticalSectionAutoLock()
{
pCMySection->UnLock();
}
private:
CMyCriticalSection *pCMySection;
};
#endif
#include <iostream>
#include <windows.h>
#include "MySemaphore.h"
#include "MyMutex.h"
#include "MyCriticalSection.h"
using namespace std;
//HANDLE g_hSemaphore = NULL;
//HANDLE g_hMutex = NULL;
CMySemaphore MySemaphore; //信号量
CMyMutex MyMutex; //互斥量
CMyCriticalSection MyCriticalSection; //临界区
DWORD WINAPI Fun(LPVOID lpParamter)
{
string strPrint((const char*)lpParamter);
int iRunTime = 0;
//执行100次跳出
while(++iRunTime<10)
{
{
CCriticalSectionAutoLock cLock(&MyCriticalSection);
cout <<"["<< iRunTime <<"]:"<< strPrint.c_str()<<endl;
}
Sleep(1); //若去掉此句 可能导致其他线程无法进入临界区,因为 cLock在这之前析构,离开临界区
}
return 0;
}
int main()
{
//创建五个子线程
string str1 = "A";
string str2 = "B";
string str3 = "C";
string str4 = "D";
string str5 = "E";
HANDLE hThread1 = CreateThread(NULL, 0, Fun, (void*)str1.c_str(), 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, Fun, (void*)str2.c_str(), 0, NULL);
HANDLE hThread3 = CreateThread(NULL, 0, Fun, (void*)str3.c_str(), 0, NULL);
HANDLE hThread4 = CreateThread(NULL, 0, Fun, (void*)str4.c_str(), 0, NULL);
HANDLE hThread5 = CreateThread(NULL, 0, Fun, (void*)str5.c_str(), 0, NULL);
//关闭线程
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);
CloseHandle(hThread5);
getchar();
// system("pause");
return 0;
}
执行结果:
这是加上Sleep(1);的运行结果,没有加上Sleep(1);的执行结果如下:
从结果我们可以看出如果没有加上Sleep(1),即在离开临界区后进行休眠,其他线程进入临界区的概率会大大降低,原因可能是由于While循环在不停的循环时,其他线程还没有那么快能够进入临界区,因此在这种情况下想让所有的线程都有机会进入临界区,则需要在离开临界区之后做短暂休眠即可。
3、Linux平台
在Linux环境下,没有Windows下的临界区的概念,但是也可以利用互斥量实现该功能。Linux下的API如下,在前面的博文里也有讲到过,可以参考http://blog.csdn.net/olansefengye1/article/details/53086141。
#include <pthread.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr); /*初始化函数*/
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);/*去初始化函数*/
int pthread_mutex_lock(pthread_mutexattr_t *attr)/*加锁*/
int pthread_mutex_unlock(pthread_mutexattr_t *attr)/*解锁*/
但是两者并不是完全一样的,他们的区别总结如下:
1、临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。
2、临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。
3、临界区和互斥体在Windows平台都下可用;Linux下只有互斥体可用。
4、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
5、互斥量:为协调共同对一个共享资源的单独访问而设计的。
C++多线程同步之临界区(CriticalSection)的更多相关文章
- VC++线程同步之临界区(CriticalSection)
1.相关文件和接口 #include <windows.h> CRITICAL_SECTION cs;//定义临界区对象 InitializeCriticalSection(&cs ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...
- 多线程(四)多线程同步_Critical Section临界区
临界区是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权.和使用mutex一样,它们都是以原子操作方式来对共享资源进行访问. 临界区又叫关键代码段,与上一篇的mutex互斥体实现的功 ...
- 【delphi】多线程与多线程同步
在 Delphi 中使用多线程有两种方法: 调用 API.使用 TThread 类; 使用 API 的代码更简单. CreateThread function CreateThread( lpThre ...
- Delphi 中多线程同步的一些处理方法
Delphi 中多线程同步的一些处理方法 当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...
- C# 多线程同步和线程通信
多线程通信 1. 当线程之间有先后的依赖关系时,属于线程之间的通信问题.也就是后一个线程要等待别的一个或多个线程全部完成,才能开始下一步的工作.可以使用: WaitHandle Class WaitH ...
- windows多线程同步总结
1.多线程同步与多线程互斥的关系 其实这也是我一直困扰的问题,在这里我只是说说我的理解.我的理解是多线程互斥是针对于多线程资源而言的. 而多线程同步是针对于多线程时序问题.由于线程的并发性导致其运行时 ...
- Windows多线程同步系列之二-----关键区
关键区对象为:CRITICAL_SECTION 当某个线程进入关键区之后,其他线程将阻塞等待,知道该线程释放关键区的拥有权. 关键区同步主要有以下几个API 初始化关键区对象,无返回值,传入一个关键区 ...
- 总结windows多线程同步互斥
windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...
随机推荐
- Python mode_a
f = open("葫芦小金刚", mode="a", encoding="utf-8") # a, append 追加, 在文件的末尾写入 ...
- NBUT 1220 SPY 2010辽宁省赛
Time limit 1000 ms Memory limit 131072 kB The National Intelligence Council of X Nation receives a ...
- java的大数运算模板
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(S ...
- 详解基本TCP套接字函数
以下讲解基本TCP套接字函数. 1.socket 函数 指定期望的通信协议类型. #include <sys/types.h> /* See NOTES */ #include ...
- C++内存管理的原则
内存管理原则,就是“谁创建,谁释放”或者说“谁申请,谁释放”. 简单地说,在代码上体现为,调用new或malloc等内存分配的人,同时需在内存使用完成后调用delete或free释放. 这个原则看似大 ...
- C语言指针使用小记 (深入理解C指针 读后小记)
最近正值过年在家,新年初一,闲暇时间无事可做便把以前看过的书籍整理了一下,顺手也把这本“深入理解C指针”的书重新读了一遍,这本书总体感觉比较简单,但是还是不免有些地方是平时没有想到过或者没有注意到的, ...
- cglib 简单 代理示例-1
引用包cglib-xxx.jar非Maven项目还需要手动引用包asm-xxx.jar业务类(不需要定义接口)cglib代理类(实现接口MethodInterceptor) 异常信息(项目只引用了cg ...
- exec函数簇
转自:http://www.cppblog.com/prayer/archive/2009/04/15/80077.html 也许有不少读者从本系列文章一推出就开始读,一直到这里还有一个很大的疑惑:既 ...
- leetcode:Valid Palindrome【Python版】
1.注意空字符串的处理: 2.注意是alphanumeric字符: 3.字符串添加字符直接用+就可以: class Solution: # @param s, a string # @return a ...
- 转 微软发布TX(LINQ To Logs And Traces)
作者 Roopesh Shenoy ,译者 马德奎 发布于 一月 09, 2014 | 微软开源技术公司于近日发布了Tx,这是一个开源项目,可以使用日志/跟踪文件辅助调试,以及创建实时监控和告警系统. ...