基于互斥量(Mutual Exclusion)的同步控制算法
实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,若是没有,进程将成功建立并设置标识实例已经存在的标记。此后再建立进程时将会经过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。函数
HANDLE WINAPI CreateMutex( _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, _In_ BOOL bInitialOwner, _In_opt_ LPCTSTR lpName );
BOOL WINAPI CloseHandle( _In_ HANDLE hObject );
BOOL WINAPI ReleaseMutex( _In_ HANDLE hMutex );
经过CreateMutex函数完成互斥量的申请和设定,若是反回NULL则代表,该互斥量已经被占用,所以申请失败,不能够运行,其余值则代表注册成功。用CloseHandle关闭互斥量,关闭后的互斥量就能够从新被注册了。经过ReleaseMutex完成一个的锁定,能够使WaitForSingleOibject得以结束。code
#include "stdafx.h" #include <Windows.h> #include <process.h> int num = 0; CRITICAL_SECTION cs; HANDLE hMutex = NULL; unsigned WINAPI ThreadFun1(void *arg) { int cnt = *(int*)arg; WaitForSingleObject(hMutex, INFINITE); for (int i = 0; i < cnt; i++) { num += 1; printf("Inc "); Sleep(10); } ReleaseMutex(hMutex); return 0; } unsigned WINAPI ThreadFun2(void *arg) { int cnt = *(int*)arg; WaitForSingleObject(hMutex, INFINITE); for (int i = 0; i < cnt; i++) { num -= 1; printf("Dec "); Sleep(10); } ReleaseMutex(hMutex); return 0; } int main() { int param = 50; HANDLE h[2]; unsigned int hd[2]; hMutex = CreateMutex(NULL, false, (LPCWSTR)"James"); h[0]= (HANDLE)_beginthreadex(NULL, 0, ThreadFun1, ¶m, 0, &hd[0]); if (h[0] == 0) { printf("Can not create a thread 1.\n"); return 0; } h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, ¶m, 0, &hd[1]); if (h[1] == 0) { printf("Can not create a thread 2.\n"); return 0; } WaitForMultipleObjects(2, h, true, INFINITE); CloseHandle(hMutex); printf("The num is %d, and end of main.\n", num); return 0; }
其运行结果以下:进程
Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Inc Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec Dec The num is 0, and end of main.
从运行结果上咱们能够看出,在Inc运行阶段,系统是被阻塞的,没有dec算法能够执行。咱们调整一下控制位置,将控制放置到循环体内部,这样咱们就会获得一个交替运行的工做过程,其代码和运行结果以下:ip
#include "stdafx.h" #include <Windows.h> #include <process.h> int num = 0; CRITICAL_SECTION cs; HANDLE hMutex = NULL; unsigned WINAPI ThreadFun1(void *arg) { int cnt = *(int*)arg; for (int i = 0; i < cnt; i++) { WaitForSingleObject(hMutex, INFINITE); num += 1; printf("Inc "); ReleaseMutex(hMutex); Sleep(10); } return 0; } unsigned WINAPI ThreadFun2(void *arg) { int cnt = *(int*)arg; for (int i = 0; i < cnt; i++) { WaitForSingleObject(hMutex, INFINITE); num -= 1; printf("Dec "); ReleaseMutex(hMutex); Sleep(10); } return 0; } int main() { int param = 50; HANDLE h[2]; unsigned int hd[2]; hMutex = CreateMutex(NULL, false, (LPCWSTR)"James"); h[0]= (HANDLE)_beginthreadex(NULL, 0, ThreadFun1, ¶m, 0, &hd[0]); if (h[0] == 0) { printf("Can not create a thread 1.\n"); return 0; } h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun2, ¶m, 0, &hd[1]); if (h[1] == 0) { printf("Can not create a thread 2.\n"); return 0; } WaitForMultipleObjects(2, h, true, INFINITE); CloseHandle(hMutex); printf("The num is %d, and end of main.\n", num); return 0; }
Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Inc Dec Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Inc Dec Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc The num is 0, and end of main.