多线程同步之互斥对象

多线程同步之互斥对象

作者:vpoet

 
对卖票问题进行线程间同步,本文将在上文的基础上,使用互斥对象对线程进行同步。



首先看看windows API
多线程同步之互斥对象_第1张图片

该函数创建一个命名或者不命名的互斥对象


lpMutexAttributes [in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpMutexAttributes is NULL, the handle cannot be inherited. 
参数lpMutexAttributes为互斥对象的安全属性,如果为NULL,则使用默认的安全属性

bInitialOwner [in] Specifies the initial owner of the mutex object. If this value is TRUE and the caller created the mutex, the calling thread obtains ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section. 
参数bInitialOwner指定该互斥对象的拥有者,若为TRUE则表明创建互斥对象的线程对其有所有权,而反之则表示创建互斥对象的线程不能对其拥有所有权


lpName [in] Pointer to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive.

If lpName matches the name of an existing named mutex object, this function requests MUTEX_ALL_ACCESS access to the existing object. In this case, thebInitialOwner parameter is ignored because it has already been set by the creating process. If the lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpName is NULL, the mutex object is created without a name.

If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Name Spaces


参数lpName指定是一个命名的互斥对象还是一个匿名的互斥对象,它们之间的区别我们留待后面再学习



多线程同步之互斥对象_第2张图片
该函数释放互斥对象的所有权,也就是说该函数将互斥对象置为有信号的状态 该函数的参数即为CreateMutex函数返回的句柄对象



在利用互斥事件进行线程同步的时候我们还需要使用一个函数WaitForSingleObject该函数将等待互斥对象有状态才返回否则一直阻塞。

接下来我们来实际动手看看,注意在CreateMutex函数的第二个参数我们置为FALSE,因为我们需要在主线程中创建该互斥对象,但是把这个
互斥对象的所有权需要轮换的交给两个子线程交替的卖票。

代码如下:
#include <windows.h>
#include <stdio.h>

static int number=10;
HANDLE Mutex;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(Mutex,INFINITE);  
        if(number>0)
        {
            printf("窗口1售出第%d张票...\n",number);
            number--;
            Sleep(1000);        
        }
        ReleaseMutex(Mutex);    
    }
    return 0;
}
DWORD WINAPI ThreadTwo(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(Mutex,INFINITE);
        if(number>0)
        {
            printf("窗口2售出第%d张票...\n",number);
            Sleep(1000);
            number--;
        }
        ReleaseMutex(Mutex);
    }
    return 0;
}


int main()
{
    HANDLE HOne,HTwo;
    Mutex=CreateMutex(NULL,FALSE,NULL);
    printf("***********************vpoet******************\n");
    HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
    printf("窗口1售票开始:\n");
    HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
    printf("窗口2售票开始:\n");
    CloseHandle(HOne);
    CloseHandle(HTwo);
    while(TRUE)
    {
        if(number==0)
        {
            printf("不好意思,票卖完了!\n");
            CloseHandle(Mutex);
            return 0;
        }
        else
        {
            continue;
        }    
    }

    return 0;
}

 


运行结果:
多线程同步之互斥对象_第3张图片

嗯 没问题,达到我们要求了。

Ok,下次博文我们再一起学习使用事件对象进行线程间同步。

 

你可能感兴趣的:(线程同步)