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; }