windows 下 Mutex和Critical Section 区别和使用
Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用黑色表示)。
| Mutex | Critical Section | |
|---|---|---|
| 性能和速度 | 慢。Mutex 是内核对象,相关函数的执行 (WaitForSingleObject,eleaseMutex)需要用户模式(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状态,其他的等待线程可以获得锁 | CriticalSection的状态不可知(undefined),以后的动作就不能保证了。 |
有人测试结果,CriticalSection用时速度比Mutex快不少。
http://blog.csdn.net/dreamfreelancer/article/details/4237272
windows下100万次加/解锁测试:
CriticalSection用时:31ms
Mutex用时:953ms
结论:CriticalSection性能远远高于Mutex(高出约30倍)。因此,在能用CriticalSection时绝不用Mutex,当然,后者可命名,而前者不行,因此,Mutex可用于进程间通信,但CriticalSection通常只能用于线程间通信。
另外,Windows上Mutex和CriticalSection都是缺省Recursive的(且不能被改变,如要实现non-recursive互斥,得用Semophore),就是同一线程在获得锁后,再次加锁不会导致阻塞,这在Linux下需要指定。 但Mutex和CriticalSection行为还是存在差异,如果在同一线程内进行了Recursive的加,解锁操作,若因为程序错误导致解锁操作次数比加锁操作多,对于Mutex,这不会有任何问题(linux和Windows都是如此),但CriticalSection表现却不同,多于必要的Unlock操作会导致下次Lock操作被阻塞。
Demo code CRITICAL_SECTION
#include <windows.h>
#include "stdio.h"
CRITICAL_SECTION g_cs;
LRESULT WINAPI WriteThread(PVOID arg)
{
EnterCriticalSection(&g_cs);
printf("WriteThread \n");
LeaveCriticalSection(&g_cs);
return 0;
}
LRESULT WINAPI ReadThread(PVOID arg)
{
EnterCriticalSection(&g_cs);
printf("ReadThread \n");
LeaveCriticalSection(&g_cs);
return 0;
}
int main1()
{
HANDLE hThreadArray[2];
InitializeCriticalSection(&g_cs);
hThreadArray[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteThread, NULL, 0, NULL);
hThreadArray[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadThread, NULL, 0, NULL);
WaitForMultipleObjects(2, hThreadArray, TRUE, INFINITE);
DeleteCriticalSection(&g_cs);
getchar();
return 0;
}
Demo code Mutex
#include <windows.h>
#include "stdio.h"
HANDLE hMutex = NULL;
LRESULT WINAPI WriteThread2(PVOID arg)
{
WaitForSingleObject(hMutex, INFINITE);
printf("WriteThread2 \n");
ReleaseMutex(hMutex);
return 0;
}
LRESULT WINAPI ReadThread2(PVOID arg)
{
WaitForSingleObject(hMutex, INFINITE);
printf("ReadThread2 \n");
ReleaseMutex(hMutex);
return 0;
}
int main()
{
HANDLE hThreadArray[2];
hMutex = CreateMutex(NULL, FALSE, NULL);
hThreadArray[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteThread2, NULL, 0, NULL);
hThreadArray[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadThread2, NULL, 0, NULL);
WaitForMultipleObjects(2, hThreadArray, TRUE, INFINITE);
getchar();
CloseHandle(hMutex);
return 0;
}
windows 下 Mutex和Critical Section 区别和使用的更多相关文章
- windows下LIB和DLL的区别与使用
共有两种库: 一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library. 一种是LIB包含 ...
- 第三篇 Nosql讲解之windows下Memcached和Memcache的区别安装(二)
一.Memcached和Memcache的区别: 网上关于Memcached和Memcache的区别的理解众说纷纭,我个人的理解是: Memcached是一个内存缓存系统,而Memcache是php的 ...
- windows下rundll32介绍
最近看书介绍rundll32可以加载dll文件并执行其中导出函数,在MSDN中我们可以看到绍http://support.microsoft.com/kb/164787/zh-cn rundll32调 ...
- spinlock,mutex,semaphore,critical section的作用与差别
某年深信服的笔试题,考的就是多线程的同步.简单的解释下方便记忆: 1.spinlock:自旋锁.是专为防止多处理器并发而引入的一种锁. 2.mutex:相互排斥量. 仅仅有拥有相互排斥对象的线程才有訪 ...
- Windows下return,exit和ExitProcess的区别和分析
通常,我们为了使自己的程序结束,会在主函数中使用return或调用exit().在windows下还有ExitProcess()和TerminateProcess()等函数. 本文的目的是比较以上几种 ...
- C++和C在linux下 和在windows下有什么区别?
一.函数库的区别 linux下的C函数库和windows下的函数库系统调用的机制不一样,Glibc包含了主要的C库.这个库提供了基本例程,用于分配内存.搜索目录.打开关闭文件.读写文件.字串处理.模式 ...
- c/c++中system函数在Linux和windows下区别
windows 在windows下的system函数中命令可以不区别大小写! 功 能: 发出一个DOS命令 #include <stdlib.h> int system(char *com ...
- 从Docker在Linux和Windows下的区别简单理解Docker的层次结构
上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...
- linux和windows下icmp的区别
实验方式:先从linux虚拟机ping windows主机,然后从windows主机ping linux虚拟机,在pc上采用wireshark抓包. 如下(只保留了关键信息) 可以看到linux发出的 ...
随机推荐
- javascript 用Activex方法调用数据库中的数据,只可用于IE
// JavaScript source code //创建数据库连接对象 var conn = new ActiveXObject("ADODB.Connection"); // ...
- Eclipse中tomcat配置
配置这两个东西 tomcat,在eclipse中启动 tomcat 才会可以访问 来自为知笔记(Wiz)
- akoj-1369 贪吃蛇
贪吃蛇 Time Limit:1000MS Memory Limit:65536K Total Submit:9 Accepted:2 Description 有童年的孩子都玩过这个经典游戏,不过这里 ...
- tps 与 事务平均响应时间关系对答
在网上看到一篇文章,tps 与 事务平均响应时间关系对答.可以帮助能更清楚的了解二者之间的关系. 问者:每秒处理的事务数和事务的平均响应时间 怎么个关系,有关系吗 kaku21:举个例子:一个高速路 ...
- python——字符串 & 正则表达
raw字符串(原始字符串) 所见即所得,例如r''My's\n'' Python转义字符 在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符.如下表: 转义字符 描述 \(在行尾时) 续 ...
- LeetCode Algorithm
LeetCode Algorithm 原文出处:[LeetCode] 算法参考:[陈皓 coolshell] 1. Two Sum 3. Longest Substring Without Repea ...
- 设计模式之桥接模式(Bridge模式)
我想大家小时候都有用蜡笔画画的经历吧.红红绿绿的蜡笔一大盒,根据想象描绘出格式图样.而毛笔下的国画更是工笔写意,各展风采.而今天我们的故事从蜡笔与毛笔说起. 设想要绘制一幅图画,蓝天.白云.绿树.小鸟 ...
- html5/css3布局(一)
响应式布局 1.响应式布局介绍 响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验,就是一个网页可以在不同设备上显示,比如:电脑.平板.手机等,不同设备都可以兼容显示.这样就不必为每一种 ...
- 2017多校第10场 HDU 6180 Schedule 贪心,multiset
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6180 题意:给了一些任务的开始时间和终止时间,现在让我们安排k台及机器,让这些任务在k太机器上最小,并 ...
- 【Linux init】systemd 服务单元管理
系统服务管理systemd Control the systemd system and service manager 控制systemd系统和服务管理,并行启动服务时充分发挥了多核处理器的性能, ...