1. 程式人生 > >Visual C++網路程式設計經典案例詳解 第3章 多執行緒與非同步套接字程式設計 實現執行緒同步 互斥物件 使用API函式操作互斥物件

Visual C++網路程式設計經典案例詳解 第3章 多執行緒與非同步套接字程式設計 實現執行緒同步 互斥物件 使用API函式操作互斥物件

互斥物件和臨界區物件和事件物件作用一樣 用於實現執行緒同步 互斥物件可以線上程中使用

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的值