基於互斥量(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.