Visual C++網路程式設計經典案例詳解 第3章 多執行緒與非同步套接字程式設計 實現執行緒同步 互斥物件 使用API函式操作互斥物件
阿新 • • 發佈:2018-12-10
互斥物件和臨界區物件和事件物件作用一樣 用於實現執行緒同步 互斥物件可以線上程中使用
CreateMutex()建立並返回互斥物件 原型如下 HANDLE CreateMutex( LPSECURITY_ATTIRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName );
呼叫成功 返回新建立的互斥物件控制代碼 否則 返回NULL
引數lpMutexAttributes指定新建立互斥物件的安全屬性 如果引數為NULL 表示互斥物件擁有預設的安全屬性
引數bInitialOwner表示互斥物件的擁有者 如果為true,則表示建立該互斥物件的執行緒擁有其所有權 如果為false,表示建立互斥物件的執行緒不能擁有互斥物件的所有權
引數lpName表示互斥物件的名稱 若引數為NULL,表示程式建立的是匿名物件 如果使用者為該引數指定值 則在程式中可以呼叫函式OpenMutex()開啟一個 命名的互斥物件
使用互斥物件實現執行緒的同步
#include <windows.h> //包含標頭檔案 #include <stdio.h> DWORD WINAPI myfun1(LPVOID lpParameter);//宣告執行緒函式 DWORD WINAPI myfun2(LPVOID lpParameter); HANDLE hmutex; int a=0; //定義全域性變數a int main() { hmutex=::CreateMutex(NULL,FALSE,NULL); //建立互斥物件並返回其控制代碼 HANDLE h1,h2; //定義執行緒控制代碼 h1=::CreateThread(NULL,0,myfun1,NULL,0,NULL); //建立執行緒1 printf("執行緒1開始執行!\r\n"); h2=::CreateThread(NULL,0,myfun2,NULL,0,NULL); //建立執行緒2 printf("執行緒2開始執行!\r\n"); ::CloseHandle(h1); //關閉執行緒控制代碼物件 ::CloseHandle(h2); ::Sleep(10000); //程式睡眠10秒 return 0; } DWORD WINAPI myfun1(LPVOID lpParameter) //執行緒函式1 { while(1) { ::WaitForSingleObject(hmutex,INFINITE); //請求互斥物件 if(a<10000) { a+=1; //變數自加 ::Sleep(1000); //執行緒睡眠1秒 printf("執行緒1:%d\r\n",a); ::ReleaseMutex(hmutex); //釋放互斥物件控制代碼 } else { ::ReleaseMutex(hmutex); //釋放互斥物件控制代碼 break; //跳出迴圈 } } return 0; } DWORD WINAPI myfun2(LPVOID lpParameter) //執行緒函式2 { while(1) { ::WaitForSingleObject(hmutex,INFINITE); //請求互斥物件 if(a<10000) { a+=1; ::Sleep(1000); printf("執行緒2:%d\r\n",a); //輸出變數 ::ReleaseMutex(hmutex); //釋放互斥物件控制代碼 } else { ::ReleaseMutex(hmutex); //釋放互斥物件控制代碼 break; //跳出迴圈 } } return 0; //執行緒正常退出 }
輸出 執行緒1開始執行! 執行緒2開始執行! 執行緒1:1 執行緒2:2 執行緒1:3 執行緒2:4 執行緒1:5 執行緒2:6 執行緒1:7 執行緒2:8 執行緒1:9 執行緒2:10 Press any key to continue
程式中,使用者首先建立互斥物件並返回其控制代碼 然後利用互斥物件控制代碼實現執行緒1和執行緒2的同步並輸出全域性變數a的值