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发出的 ...
随机推荐
- Oracle数据库常用关键字以及函数
常用关键字 insert into---插入数据 delete---删除数据 update---更新一条数据 select---实际工作中尽量不要写* set---设置某些属性 where---给执行 ...
- vue的一些坑(第一天)
1:刚开始在创建项目的时候一直出现vue不是内部或外部命令 关于这个的解决方案网上给出的很多的解决方案是配置环境,这个我就不在赘述了: 但是我觉得那样太麻烦,就没用,只是重新 npm i vue-cl ...
- Aleta病毒
文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份!!! 文件一定要及时备份 ...
- Problem of Uninstall Cloudera: Can't Add Hdfs and Reported Cannot Find CDH's bigtop-detect-javahome
[toc] 1. Problem We wrote a shell script to uninstall Cloudera Manager(CM) that run in a cluster wit ...
- Window检测网络连接情况
Window检测网络连接情况 #include "Wininet.h" #pragma comment(lib,"Wininet.lib") DWORD fla ...
- Linux下C的线程同步机制
C里提供了保证线程安全性的三种方法: (添加头文件#include<pthread.h>,pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a, ...
- C#多线程的用法5-线程间的协作Monitor
之前我们使用lock快捷方式,实现了多线程对同一资源的共享.在C#中lock实际上是Monitor操作的简化版本. 下面使用Monitor来完成之前的lock功能,你可以在此做一下对照: privat ...
- 使用jQuery实现简单的tab框
html代码 <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta ...
- 一个项目经理对主流项目管理工具的对比:禅道VS华为软件开发云
禅道与软件开发云对比分析报告 1. 产品介绍 禅道是易软天创出品的一款项目管理软件,集产品管理.项目管理.测试管理.文档管理.组织管理于一体,覆盖了项目管理和测试管理的核心流程. 华为软件开发云 (D ...
- C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件..很很很很重要..),附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 本篇..基 ...