互斥量的用途和临界区很像。它与临界区的差别在于可以跨线程使用,可以用来互斥进行多个线程间的数据访问,但是是以牺牲速度为代价的。只有临界区是非核心对象,那么互斥量就是一个核心对象了。核心对象的特点是有所谓的引用计数。所著一个未被拥有的互斥量,比锁住一个未被拥有的临界区需要花费几乎100倍的时间(数据引用自《Visual C++ 6.0编程学习捷径》)。
#include<stdio.h> #include<process.h> #include<windows.h> volatile long g_nLoginCount; const int THREAD_NUM = 10; volatile long g_num; CRITICAL_SECTION g_thread; HANDLE g_Mutex; unsigned int __stdcall ThreadFun(void *pPM){ int thread_id=*((int *)pPM); Sleep(50); WaitForSingleObject(g_Mutex,INFINITE); // EnterCriticalSection(&g_thread); g_num++; Sleep(0); printf("ID : %d 全局:%d\n",thread_id,g_num); // LeaveCriticalSection(&g_thread); ReleaseMutex(&g_Mutex); return 0; } int main(){ InitializeCriticalSection(&g_thread); g_Mutex = CreateMutex(NULL,FALSE,NULL); g_nLoginCount = 0; g_num=0; HANDLE handle[THREAD_NUM]; int num=20; g_nLoginCount = 0; for(int i = 0;i < THREAD_NUM; i++){ handle[i] = (HANDLE)_beginthreadex(NULL,0,ThreadFun,&i,0,NULL); } WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE); CloseHandle(g_Mutex); DeleteCriticalSection(&g_thread); return 0; }
结果:
这样也能达到关键段的效果,但互斥量比关键段有更多的优点:
1、互斥量常用与多进程间多线程的互斥,关键段只用于进程内多线程的互斥。
2、互斥量可以处理“遗弃问题”,即其他进程中某个线程因为一些原因挂了的话,系统检测到该线程占用互斥量,就会把该互斥量释放掉,以免其他线程一直等待下去。
最后总结下互斥量Mutex:
1.互斥量是内核对象,它与关键段都有“线程所有权”所以不能用于线程的同步。
2.互斥量能够用于多个进程之间线程互斥问题,并且能完美的解决某进程意外终止所造成的“遗弃”问题。
参考:http://blog.csdn.net/morewindows/article/details/7470936,http://liuviphui.blog.163.com/blog/static/2022730842013363138649/