转载自:http://blog.csdn.net/morewindows/article/details/7470936
步骤:
1、CreateMutex,创建互斥量
2、用WaitForSingleObject,获得互斥量
3、ReleaseMutex,当用完互斥量后,就释放。其实就是将其内核记录的线程ID变为0
对互斥量的个人理解:
1、互斥量与临界区的功能是一样的。
2、互斥量是一个内核对象,因为是一个内核对象,所以能被更多的线程、进程所共享
3、互斥量能够很好地处理“遗弃”问题,避免让其它线程、进程,进入“忙等”状态。
4、临界区只是一个用户模式下的同步对象。
5、互斥量与临界区一样都是拥有线程权,即创建同步对象的线程,可以忽略同步对象的存在而执行,所以这两个同步对象,都只适合互斥操作,而不适合同步。(互斥是一种特殊的同步)
代码:
//经典线程同步问题 互斥量Mutex
#include <stdio.h>
#include <process.h>
#include <windows.h>
long g_nNum;
unsigned int __stdcall Fun(void *pPM);
const int THREAD_NUM = 10;
//互斥量与关键段
HANDLE g_hThreadParameter;
CRITICAL_SECTION g_csThreadCode;
int main()
{
printf(" 经典线程同步 互斥量Mutex\n");
printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
//初始化互斥量与关键段 第二个参数为TRUE表示互斥量为创建线程所有
g_hThreadParameter = CreateMutex(NULL, FALSE, NULL);
InitializeCriticalSection(&g_csThreadCode);
HANDLE handle[THREAD_NUM];
g_nNum = 0;
int i = 0;
while (i < THREAD_NUM)
{
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
WaitForSingleObject(g_hThreadParameter, INFINITE); //等待互斥量被触发
i++;
}
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
//销毁互斥量和关键段
CloseHandle(g_hThreadParameter);
DeleteCriticalSection(&g_csThreadCode);
for (i = 0; i < THREAD_NUM; i++)
CloseHandle(handle[i]);
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
int nThreadNum = *(int *)pPM;
ReleaseMutex(g_hThreadParameter);//触发互斥量
Sleep(50);//some work should to do
EnterCriticalSection(&g_csThreadCode);
g_nNum++;
Sleep(0);//some work should to do
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);
return 0;
}
结果: