利用互斥量实现线程同步

        互斥量(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID和一个计数器。其中,ID用于标识哪个线程拥有该互斥量,计数器用于指明线程拥有对象的次数。CreateMutex函数用于创建或打开一个命名或匿名的互斥量,描述如下:

HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES  lpMutexAttributes,   // 指向安全属性的指针
BOOL  bInitialOwner,   // 初始化互斥对象的所有者
LPCTSTR  lpName  // 指向互斥对象名的指针
);
参数lpMutexAttributes为指向安全属性的结构体,一般设置为null,表示默认的安全性。

参数bInitialOwer为互斥量的初始拥有者,如果为真,则创建该互斥量的线程为拥有者。反之,创建线程捕获得拥有权。

参数lpName为互斥量的名称,如果传值为null,表示为匿名对象。

        另外,还有两个函数,一个是WaitForSingleObject用于主动请求共享对象的使用权,原型如下:

DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
参数hHandle为请求对象的句柄,这里是指信号量的句柄

参数dwMilliseconds为等待时间,可以传递三种形式的参数,一个是毫秒数,一个是INFINITE,一个是0,这些代表了经过多少时间,如果没有信号则函数返回,返回值的含义具体查看MSDN。关于利用互斥量实现线程同步的例子如下:

#include 
#include 

DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int index = 0;
int tickets = 100;
HANDLE hMutex;

int main()
{
    HANDLE hThread1;
    HANDLE hThread2;
 
    //创建互斥对象
	hMutex = CreateMutex(NULL, FALSE, LPCTSTR("tickets"));
    
	if(hMutex)
    {
        if (ERROR_ALREADY_EXISTS == GetLastError())
        {
            std::cout << "only one instance can run!" << std::endl;
            return 0;
        }
    }
     //创建线程

    hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
    hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
    
    CloseHandle(hThread1);   
    CloseHandle(hThread2);
    Sleep(4000);

    std::cout<< "now is the main thread in running\n";
    system("pause");
    return 0;
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
    while (true)
    {
        
        WaitForSingleObject(hMutex,INFINITE);
        if (tickets>0)
        {
            Sleep(1); 
            std::cout << "thread1 sell ticket :" << tickets-- << std::endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
 
    return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
    while (true)
    {
      
        WaitForSingleObject(hMutex,INFINITE);
        if (tickets>0)
        {
            Sleep(1);
            std::cout << "thread2 sell ticket :" << tickets-- << std::endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
    
    return 0;
}
利用互斥量实现线程同步_第1张图片

        对于一个互斥量来说,我们应做到谁拥有谁释放。如果同一线程多次拥有互斥量,则会增加互斥量的使用次数。当然要想让其他线程使用该互斥量,那么首先就要释放同等的次数,这样当互斥量变为有信号状态,其他线程就可以使用该互斥量了。

你可能感兴趣的:(windows编程)