Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。
Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。
#include "stdafx.h"
#include <conio.h>
#include <Windows.h>
// 临界资源
int g_sum = 0;
// 1、声明信号量对象句柄
HANDLE g_hSemaphore;
DWORD WINAPI ThreadFunc1(LPVOID lpParam);
DWORD WINAPI ThreadFunc2(LPVOID lpParam);
int _tmain(int argc, _TCHAR* argv[])
{
// 为了演示方便,输入s开始
printf("请输入“s”开始创建线程:");
while (getchar() != 's')
{
::Sleep(200);
}
printf("\n");
// 2、创建信号量对象 分别用下面三行代码试试
//g_hSemaphore = ::CreateSemaphore(NULL, 0, 2, NULL);
//g_hSemaphore = ::CreateSemaphore(NULL, 1, 2, NULL);
g_hSemaphore = ::CreateSemaphore(NULL, 2, 2, NULL);
// 创建线程1
HANDLE h1 = ::CreateThread(NULL, 0, ThreadFunc1, NULL, 0, NULL);
if (h1 != NULL)
{
printf("主线程:线程1创建成功!\n");
}
else
{
printf("主线程:线程1创建失败!\n");
}
// 创建线程2
HANDLE h2 = ::CreateThread(NULL, 0, ThreadFunc2, NULL, 0, NULL);
if (h2 != NULL)
{
printf("主线程:线程2创建成功!\n");
}
else
{
printf("主线程:线程2创建失败!\n");
}
// 主线程
//等待子线程结束
::WaitForSingleObject(h1, INFINITE);
::WaitForSingleObject(h2, INFINITE);
while (1)
{
if (_getch() == 'q')
{
break;
}
::Sleep(100);
}
::CloseHandle(h1);
::CloseHandle(h2);
::CloseHandle(g_hSemaphore);
return 0;
}
DWORD WINAPI ThreadFunc1(LPVOID lpParam)
{
// 3、请求信号量对象
::WaitForSingleObject(g_hSemaphore, INFINITE);
int n = 5;
while (n-- > 0)
{
g_sum += 1;
printf("线程1:g_sum 1111= %d\n", g_sum);
::Sleep(1000);
}
// 4、释放
::ReleaseSemaphore(g_hSemaphore, 1, NULL);
printf("线程1:执行完毕!\n");
return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID lpParam)
{
// 3、请求信号量对象
::WaitForSingleObject(g_hSemaphore, INFINITE);
int n = 5;
while (n-- > 0)
{
g_sum += 10;
printf("线程2:g_sum 2222= %d\n", g_sum);
::Sleep(2000);
}
// 4、释放
::ReleaseSemaphore(g_hSemaphore, 1, NULL);
printf("线程2:执行完毕!\n");
return 0;
}