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发出的 ...
随机推荐
- Spring+SpringMVC+MyBatis+easyUI整合
进阶篇 Spring+SpringMVC+MyBatis+easyUI整合进阶篇(一)设计一套好的RESTful API 优化篇 Spring+SpringMVC+MyBatis+easyUI整合优化 ...
- iOS设置状态栏样式
iOS设置状态栏样式可以使用两种方式. 方式一: 直接在需要改变默认状态栏样式的控制器中实现一个方法(其他任何事情都不用做): // 返回状态栏的样式 - (UIStatusBarStyle)pref ...
- 如何开发自己的搜索帝国之Elasticsearch
搜索引擎是什么? 搜索引擎是指根据一定的策略.运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的信息展示给用户的系统.搜索引擎包括全文索引.目录索引 ...
- linux下安装log4cplus
wget http://sourceforge.net/projects/log4cplus/files/log4cplus-stable/1.1.2/log4cplus-x.x.x.tar.gz t ...
- 放开那个UI 妹子,让我来(上)
一.前言 今天要学习的内容:今天主要是稍微总结一下,页面中如何用字体代替图片,省事,省时,方便,实用! 小苏啰嗦:人都是有惰性的.真的.刚开始我们有一个经验丰富的美工,加上我们关系又非常好,以至于每次 ...
- jquery左右切换的无缝滚动轮播图
1.HTML结构: <head> <script type="text/javascript" src="../jquery-1.8.3/jquery. ...
- 关于JS中数组的分析操作
JS数组的基础操作代码: <script type="text/javascript"> 数组的三种定义 var arr1 = new Array( ...
- 你不可错过的二维码生成与解析-java后台与前端js都有
1.二维码分类 二维条码也有许多不同的码制,就码制的编码原理而言,通常分为三种类型. 线性堆叠式二维码 编码原理: 建立在一维条码基础之上,按需要堆积成两行或多行. 图示: 矩阵式二维码 最常用编 ...
- JavaScript语法作业
相亲过程:你有房子么?你有钱么?你有能力么?[结婚吧][先买房子在结婚][先赚钱再买房子再结婚]都没有[拜拜~~]利用if嵌套做相亲过程 <script> var a=prompt(&qu ...
- storm学习笔记(一)
1.storm介绍 storm是一种用于事件流处理的分布式计算框架,它是有BackType公司开发的一个项目,于2014年9月加入了Apahche孵化器计划并成为其旗下的顶级项目之一. ...