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发出的 ...
随机推荐
- asp.net 动态压缩、切割图片,并做缓存处理机制
在asp.net中,新建一个handler,把需要切割的网内图片,通过调用此URL来切割并缓存.http://localhost:53829/CacheImage/ResizeImage.ashx?s ...
- js存款计算器原生小demo
大家好,本人是初入前端的一枚程序猿,深知js底层开发的重要性,这也是我的软肋所在(曾经以为),渐渐的明白了一个道理,饭要一口口吃,路要一步步走,这也是我想告诉给所有刚刚进入IT行业的技术员们,沉下心, ...
- HTML <hr>标签
HTML的<hr>标签用来插入一个水平分割线以把文档分成几部分. 水平线通常显示为一条突出的或者凹下去的线条. 在页面中特定的位置插入水平线,既能使页面的结构清晰,又能使整个页面显得美观, ...
- js的call,apply,bind的使用与区别
在原生js中会有三个很常见的函数,call,apply,bind 他们的作用就是改变当前函数的this指针, 但是细微来说他们还是有不同的. 1)call,apply都是执行某一函数,发现this有变 ...
- QtWebKit/QtWebEngine移植差异(网摘)
QtWebKit/QtWebEngine移植差异 原文出处:[wiki.qt.io] This guide gives an overview of the differences between t ...
- C#多线程的用法5-线程间的协作Monitor
之前我们使用lock快捷方式,实现了多线程对同一资源的共享.在C#中lock实际上是Monitor操作的简化版本. 下面使用Monitor来完成之前的lock功能,你可以在此做一下对照: privat ...
- Orleans的集群构建
Orleans的集群构建 这是Orleans系列文章中的一篇.首篇文章在此 听闻一周前,微软公布了.net core2.0,以及各种各样的其他core2.0.大家都很兴奋.微妈的诚意真是满满的.这次开 ...
- 关于curl / curl_multi的一些实验
几天没写了,主要都是自己的学习过程,贴一下curl / curl_multi_exec的一些代码,mark一下. <?php /** * Created by PhpStorm. * User: ...
- shell中while循环的陷阱
在写while循环的时候,发现了一个问题,在while循环内部对变量赋值.定义变量.数组定义等等环境,在循环外面失效. 一个简单的测试脚本如下: #!/bin/bash echo "abc ...
- 关于批量插入数据之我见(100万级别的数据,mysql) (转)
因前段时间去面试,问到如何高效向数据库插入10万条记录,之前没处理过类似问题,也没看过相关资料,结果没答上来,今天就查了些资料,总结出三种方法: 测试数据库为MySQL!!! 方法一: public ...