互斥体

DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // time-out interval
);

功能说明:

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止.

hHandle:

内核对象句柄,可以是进程也可以是线程.

dwMilliseconds:

等待时间,单位是毫秒 INFINITE(-1)一直等待

返回值:

WAIT_OBJECT_0(0) 等待对象变为已通知

WAIT_TIMEOUT(0x102) 超时


特别说明:

1、内核对象中的每种对象都可以说是处于已通知或未通知的状态之中

2、这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的

3、当线程正在运行的时候,线程内核对象处于未通知状态

4、当线程终止运行的时候,它就变为已通知状态

5、在内核中就是个BOOL值,运行时FALSE 结束TRUE

代码演示:

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
for(int i=0;i<5;i++)
{
printf("+++++++++ ");
Sleep(1000);
}
return 0;
}

int main(int argc, char* argv[])
{

//创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL);

DWORD dwCode = ::WaitForSingleObject(hThread1, INFINITE);

MessageBox(0,0,0,0);

return 0;
}


DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in array
CONST HANDLE *lpHandles, // object-handle array
BOOL bWaitAll, // wait option
DWORD dwMilliseconds // time-out interval
);

功能说明:

同时查看若干个内核对象的已通知状态

nCount:

要查看内核对象的数量

lpHandles:

内核对象数组

bWaitAll:

等到类型 TRUE 等到所有变为已通知 FALSE 只要有一个变为已通知

dwMilliseconds:

超时时间

INFINITE一直等待

返回值:

bWaitAll为TRUE时,返回WAIT_OBJECT_0(0) 代码所以内核对象都变成已通知

bWaitAll为FALSE时,返回最先变成已通知的内核对象在数组中的索引

WAIT_TIMEOUT(0x102) 超时


代码演示:

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
for(int i=0;i<5;i++)
{
printf("+++++++++ ");
Sleep(1000);
}
return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
for(int i=0;i<3;i++)
{
printf("--------- ");
Sleep(1000);
}

return 0;
}


int main(int argc, char* argv[])
{

HANDLE hArray[2];

//创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL);

//创建一个新的线程
HANDLE hThread2 = ::CreateThread(NULL, 0, ThreadProc2,
NULL, 0, NULL);

hArray[0] = hThread1;
hArray[1] = hThread2;

DWORD dwCode = ::WaitForMultipleObjects(2, hArray,FALSE,INFINITE);

MessageBox(0,0,0,0);

return 0;
}



进程一:

HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");


进程二:

HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");

WaitForSingleObject(g_hMutex,INFINITE);

//逻辑代码

ReleaseMutex(g_hMutex);


进程三:

HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");

WaitForSingleObject(g_hMutex,INFINITE);

//逻辑代码

ReleaseMutex(g_hMutex);





互斥体与临界区的区别:

1、临界区只能用于单个进程间的线程控制.

2、互斥体可以设定等待超时,但临界区不能.

3、线程意外终结时,Mutex可以避免无限等待.

4、Mutex效率没有临界区高.

以下是抢红包程序:

// hongbao.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include<stdio.h>

HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HANDLE hMutex;
int num = 1000;

DWORD WINAPI ProcThread1(LPVOID lpParameter)
{
    TCHAR szBuff[10] = {0};
    int flag =  0;
    HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "XYZ");
    while(num >= 50)
    {
        WaitForSingleObject(hMutex, INFINITE);
    //    GetWindowText(hEdit1, szBuff, 10);
    //    sscanf(szBuff, "%d", &flag);
        num -= 50;
        flag += 50;    
        sprintf(szBuff, "%d", num);
        SetWindowText(hEdit1, szBuff);
        memset(szBuff, 0, 10);
        sprintf(szBuff, "%d", flag);
        SetWindowText(hEdit2, szBuff);
        ExitThread(2);
        ReleaseMutex(hMutex);
        Sleep(1000);
    }

    return 0;
}

DWORD WINAPI ProcThread2(LPVOID lpParameter)
{
    TCHAR szBuff[10] = {0};
    int flag =  0;
    HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "XYZ");
    while(num >= 50)
    {
        WaitForSingleObject(hMutex, INFINITE);
    //    GetWindowText(hEdit1, szBuff, 10);
    //    sscanf(szBuff, "%d", &flag);
        num -= 50;
        flag += 50;    
        sprintf(szBuff, "%d", num);
        SetWindowText(hEdit1, szBuff);
        memset(szBuff, 0, 10);
        sprintf(szBuff, "%d", flag);
        SetWindowText(hEdit3, szBuff);
        ReleaseMutex(hMutex);
        Sleep(2000);
    }

    return 0;
}

DWORD WINAPI ProcThread3(LPVOID lpParameter)
{
    TCHAR szBuff[10] = {0};
    int flag =  0;
    HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "XYZ");
    while(num >= 50)
    {
        WaitForSingleObject(hMutex, INFINITE);
    //    GetWindowText(hEdit1, szBuff, 10);
    //    sscanf(szBuff, "%d", &flag);
        num -= 50;
        flag += 50;    
        sprintf(szBuff, "%d", num);
        SetWindowText(hEdit1, szBuff);
        memset(szBuff, 0, 10);
        sprintf(szBuff, "%d", flag);
        SetWindowText(hEdit4, szBuff);
        ReleaseMutex(hMutex);
        Sleep(3000);
    }
    return 0;

}


DWORD WINAPI  ProcThread(LPVOID lpParameter)
{
    hMutex = CreateMutex(NULL, FALSE, "XYZ");
    HANDLE hHandleArr[3];

    hHandleArr[0] = ::CreateThread(NULL, 0, ProcThread1, NULL, 0, NULL);
    hHandleArr[1] = ::CreateThread(NULL, 0, ProcThread2, NULL, 0, NULL);
    hHandleArr[2] = ::CreateThread(NULL, 0, ProcThread3, NULL, 0, NULL);
    
    ::WaitForMultipleObjects(3, hHandleArr, TRUE, INFINITE);
    ::CloseHandle(hMutex);
    return 0;
}

BOOL CALLBACK ProcDialog(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
        hEdit1 = GetDlgItem(hwnd, IDC_EDIT1);
        SetWindowText(hEdit1, "1000");
        hEdit2 = GetDlgItem(hwnd, IDC_EDIT2);
        SetWindowText(hEdit2, "0");
        hEdit3 = GetDlgItem(hwnd, IDC_EDIT3);
        SetWindowText(hEdit3, "0");
        hEdit4 = GetDlgItem(hwnd, IDC_EDIT4);
        SetWindowText(hEdit4, "0");
        break;
    case WM_CLOSE:
        EndDialog(hwnd, 0);
        break;
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case IDC_BUTTON1:
            HANDLE hThread = ::CreateThread(NULL, 0, ProcThread, NULL, 0, NULL);
            ::CloseHandle(hThread);
            return TRUE;
        }
        break;
    }
    return FALSE;

}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     // TODO: Place code here.
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, ProcDialog);
    return 0;
}
原文地址:https://www.cnblogs.com/Lu3ky-Athena/p/13720912.html