C++多线程之使用Mutex和Critical_Section
来源:互联网 发布:淘宝竞拍是真的吗 编辑:程序博客网 时间:2024/06/01 07:28
Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用绿色表示)。
Mutex
Critical Section
性能和速度
慢。
Mutex 是内核对象,相关函数的执行 (WaitForSingleObject,
ReleaseMutex)需要用户模式(User Mode)到内核模式
(Kernel Mode)的转换,在x86处理器上这种转化一般要
发费600个左右的 CPU指令周期。
快。
Critical Section本身不是内核对象,相关函数
(EnterCriticalSection,LeaveCriticalSection)
的调用一般都在用户模式内执行,在x86处理器上
一般只需要发费9个左右的 CPU指令周期。只有
当想要获得的锁正好被别的线程拥有时才会退化
成和Mutex一样,即转换到内核模式,发费600个
左右的 CPU指令周期。
能否跨越进程(Process)边界
可以
不可
定义写法
HANDLE hmtx;
CRITICAL_SECTION cs;
初始化写法
hmtx= CreateMutex (NULL, FALSE, NULL);
InitializeCriticalSection(&cs);
结束清除写法
CloseHandle(hmtx);
DeleteCriticalSection(&cs);
无限期等待的写法
WaitForSingleObject (hmtx, INFINITE);
EnterCriticalSection(&cs);
0等待(状态检测)的写法
WaitForSingleObject (hmtx, 0);
TryEnterCriticalSection(&cs);
任意时间等待的写法
WaitForSingleObject (hmtx, dwMilliseconds);
不支持
锁释放的写法
ReleaseMutex(hmtx);
LeaveCriticalSection(&cs);
能否被一道用于等待其他内核对象
可以(使用WaitForMultipleObjects,
WaitForMultipleObjectsEx,
MsgWaitForMultipleObjects,
MsgWaitForMultipleObjectsEx等等)
不可
当拥有锁的线程死亡时
Mutex变成abandoned状态,其他的等待线程可以获得锁。
Critical Section的状态不可知(undefined),
以后的动作就不能保证了。
自己会不会锁住自己
不会(对已获得的Mutex,重复调用WaitForSingleObject不会
锁住自己。但最后你别忘了要调用同样次数的
ReleaseMutex)
不会(对已获得的Critical Section,重复调用
EnterCriticalSection不会锁住自己。但最后
你别忘了要调用同样次数的
LeaveCriticalSection)
下面是一些补充:
l 请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的可能就越小。
l 每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也同样。若你把这个问题和Win32 structured exception或C++ exception一起考虑,你会发现问题并不是那么简单。自定义一个封装类可能是一种解决方案,以Critical Section为例的代码如下所示:
class csholder
{
CRITICAL_SECTION *cs;
public:
csholder(CRITICAL_SECTION *c): cs(c)
{ EnterCriticalSection(cs); }
~csholder() { LeaveCriticalSection(cs); }
};
CRITICAL_SECTION some_cs;
void foo()
{
// ...
csholder hold_some(&some_cs);
// ... CS protected code here
// at return or if an exception happens
// hold_some's destructor is automatically called
}
l 根据你的互斥范围需求的不同,把Mutex或Critical Section定义为类的成员变量,或者静态类变量。
l 若你想限制访问的全局变量只有一个而且类型比较简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列函数来保证一个线程写多个线程读。
Demo程序
CRITICAL_SECTION g_cs;
{
cout << index++ << endl;
}
{
cout << index++ << endl;
}
void changeMe3()
{
cout << index++ << endl;
}
{
while(1)
{
Sleep(1600); //sleep 1.6 s
// 进入临界区
EnterCriticalSection(&g_cs);
//WaitForSingleObject(hMutex, INFINITE);
//cout << "a" << index++ << endl;
changeMe();
changeMe2();
changeMe3();
//ReleaseMutex(hMutex);
LeaveCriticalSection(&g_cs);
}
return 0;
}
{
while(1)
{
Sleep(2000); //sleep 2 s
// 进入临界区
EnterCriticalSection(&g_cs);
// 等待互斥对象通知
//WaitForSingleObject(hMutex, INFINITE);
changeMe();
changeMe2();
changeMe3();
//ReleaseMutex(hMutex);
// 离开临界区
LeaveCriticalSection(&g_cs);
}
return 0;
}
{
// 创建互斥对象
//hMutex = CreateMutex(NULL, TRUE, NULL);
// 初始化临界区
InitializeCriticalSection(&g_cs);
HANDLE hThread2;
hThread1 = CreateThread(NULL, 0, th1, NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, th2, NULL, 0, NULL);
int k;
cin >> k;
printf("Hello World!\n");
return 0;
}
- C++多线程之使用Mutex和Critical_Section
- C++多线程之使用Mutex和Critical_Section
- C++多线程之使用Mutex和Critical_Section
- C++多线程之使用Mutex和Critical_Section
- C++多线程之使用Mutex和Critical_Section
- c++多线程编程中Mutex和Critical_Section的区别
- 跨平台的多线程互斥访问控制(Mutex和Critical_Section)
- C# 多线程系列之Mutex使用
- 线程同步问题,CRITICAL_SECTION和Mutex哪个更快
- 多线程同步之CRITICAL_SECTION(临界区)
- 关于多线程与CRITICAL_SECTION的使用
- C++多线程之Mutex
- 多线程之互斥量mutex
- QNX多线程之Mutex
- 多线程之Mutex(互斥量)
- linux多线程之mutex
- Mutex与CRITICAL_SECTION的比较
- 线程同步:CRITICAL_SECTION, Mutex , Event
- 批量Load到HBase
- understand官方网站,可以学习它的使用
- 关于iframe自适应高度的做法 在同一个域下面
- 利用xcopy命令实现本地文件复制到远程服务器的方法
- Response.ContentType详细说明
- C++多线程之使用Mutex和Critical_Section
- 学习
- jQuery中的事件
- Sprite Kit教程:如何拖放Sprites
- 交叉编译支持多线程的Android版X264库
- libvirt error: Failed to reconnect to the hypervisor
- Android之使用Android-query框架进行开发(一)
- Windows7 64位系统搭建Cocos2d-x 2.2.1最新版以及Android交叉编译环境(详细教程)
- Apache Apollo说明