zoukankan      html  css  js  c++  java
  • 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 
    ");
    
    	LeaveCriticalSection(&g_cs);
    	return 0;
    }
    
    LRESULT WINAPI ReadThread(PVOID arg)
    {
    	EnterCriticalSection(&g_cs);
    
    	printf("ReadThread 
    ");
    
    	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 
    ");
    
    	ReleaseMutex(hMutex);
    	return 0;
    }
    
    LRESULT WINAPI ReadThread2(PVOID arg)
    {
    	WaitForSingleObject(hMutex, INFINITE);
    
    	printf("ReadThread2 
    ");
    
    	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;
    }
    
  • 相关阅读:
    数据结构(线性结构-栈)
    数据结构(线性结构-队列)
    数据结构(树状结构-二叉树)
    数据结构(树状结构-树)
    数据结构(线性结构-串)
    数据结构(堆)
    数据结构(图)
    查找(静态查找表)
    查找(动态查找表)
    查找(哈希表)
  • 原文地址:https://www.cnblogs.com/langzou/p/7373356.html
Copyright © 2011-2022 走看看