临界区用于同一进程中的不同线程,互斥体可以应用于不同的进程,位于内核区;
我们可以做以下的实验,开两个进程,创建互斥体;两进程如下:
/**
*A进程
*/
#include <stdio.h>
#include <windows.h>
int main()
{
//创建互斥体
HANDLE g_hMutex = CreateMutex(NULL, FALSE, TEXT("Mutex"));
//等待互斥体
WaitForSingleObject(g_hMutex, INFINITE);
for (INT i = 0; i < 10; i++){
Sleep(1000);
printf("A进程:%d\n", i);
}
//释放互斥体
ReleaseMutex(g_hMutex);
return 0;
}
/**
*B进程
*/
#include <stdio.h>
#include <windows.h>
int main()
{
//创建互斥体
HANDLE g_hMutex = CreateMutex(NULL, FALSE, TEXT("Mutex"));
//等待互斥体
WaitForSingleObject(g_hMutex, INFINITE);
for (INT i = 0; i < 10; i++){
Sleep(1000);
printf("B进程:%d\n", i);
}
//释放互斥体
ReleaseMutex(g_hMutex);
return 0;
}
先开A进程然后立即开启B进程,可以看到B进程并没有立即运行,而是等到了A进程运行结束才开始运行;
互斥体与临界区的区别:
1.临界区只能用于单个进程中的线程控制;
2.互斥体可以设置超时等待,临界区不能;
3.线程意外终结后,互斥体可以避免无限循环;
4.Mutet效率没有临界区高;
运用互斥体,我们可以防止进程被多开;实例代码如下:
/**
*防止多开
*/
#include <stdio.h>
#include <windows.h>
int main()
{
//创建互斥体
HANDLE g_hMutex = CreateMutex(NULL, FALSE, TEXT("Mutex"));
DWORD lastError = GetLastError();
if (g_hMutex){
if (ERROR_ALREADY_EXISTS == lastError){
CloseHandle(g_hMutex);
return 0;
}
} else {
printf("程序运行出错\n");
return 0;
}
while (1){
Sleep(1000);
printf("进程运行中......\n");
}
//释放互斥体
ReleaseMutex(g_hMutex);
return 0;
}