您的位置:首页 > 编程语言 > C语言/C++

进程、线程同步互斥学习 —— 互斥器

2015-06-26 13:34 615 查看
关于互斥器,先看MSDN介绍:

Mutex Objects
A mutex object is a synchronization object whose state is set to signaled when it is not owned by any thread, and nonsignaled
when it is owned. Only one thread at a time can own a mutex object, whose name comes from the fact that it is useful in coordinating mutually exclusive access to a shared resource. 

即:Mutex可以被某一个线程在某一时刻被单独拥有,Mutex从有信号转变成无信号。

初始化

A thread uses the
CreateMutex orCreateMutexEx function to create a mutex object. The creating thread can request immediate ownership
of the mutex object and can also specify a name for the mutex object. It can also create an unnamed mutex. 

HANDLE WINAPI CreateMutex(
__in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
__in      BOOL bInitialOwner,
__in_opt  LPCTSTR lpName
);
HANDLE WINAPI CreateMutexEx(
__in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
__in_opt  LPCTSTR lpName,
__in      DWORD dwFlags,
__in      DWORD dwDesiredAccess
);


lpMutexAttributes SECURITY_ATTRIBUTES  安全属性。

bInitialOwner 如创建进程希望立即拥有互斥体,则设为TRUE,一个互斥体同时只能由一个线程拥有。

lpName String 指定互斥体对象的名字。

dwFlags  0或者CREATE_MUTEX_INITIAL_OWNER(0x00000001)

dwDesiredAccess  访问权限

当我们在做某俩进程互斥的时候,可用OpenMutex打开已存在的Mutex

HANDLE WINAPI OpenMutex(
__in  DWORD dwDesiredAccess,
__in  BOOL bInheritHandle,
__in  LPCTSTR lpName
);


wait操作

Any thread with a handle to a mutex object can use one of thewait functions to request ownership of the mutex object. 

我们可以用wait functions对Mutex进行等待操作

比如 SignalObjectAndWait,WaitForSingleObject,WaitForSingleObjectEx当某个线程得到Mutex时,此Mutex变为无信号状态。

signal操作

If the mutex object is owned by another thread, the wait function blocks the requesting thread until the owning thread releases the mutex object using theReleaseMutex
function.

BOOL WINAPI ReleaseMutex(
__in  HANDLE hMutex
);
即:释放Mutex,Mutex变为有信号状态。

测试代码:

Mutex.h

#pragma once
#include <windows.h>

class ILock
{
public:
virtual void lock() = 0;
virtual void unlock() = 0;
};

class _CMutex : public ILock
{
public:
_CMutex();
~_CMutex();

virtual void lock();
virtual void unlock();
private:
HANDLE m_hMutex;
};

class CLock
{
public:
CLock(ILock&);
~CLock();
private:
ILock& m_lock;
};


Mutex.cpp

#include "stdafx.h"
#include "Mutex.h"
#include <assert.h>

_CMutex::_CMutex()
{
m_hMutex = ::CreateMutex(NULL, FALSE, NULL);
assert(m_hMutex);
}

_CMutex::~_CMutex()
{
::CloseHandle(m_hMutex);
}

void _CMutex::lock()
{
WaitForSingleObject(m_hMutex, INFINITE);
}

void _CMutex::unlock()
{
::ReleaseMutex(m_hMutex);
}

CLock::CLock(ILock& locker) : m_lock(locker)
{
m_lock.lock();
}

CLock::~CLock()
{
m_lock.unlock();
}
test.cpp
// Mutex_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <process.h>
#include "Mutex.h"
#define THREADCOUNT 10
_CMutex g_mutex;
int nFood = 0;

unsigned int WINAPI EatThread(void *pParam)
{
int i = (int)pParam;
int nHasEaten = 0;
while (true)
{
CLock lock(g_mutex);
if (nFood > 0)
{
Sleep(100);
std::cout << "消费者" << i << "进行消费,已经吃掉(" << ++nHasEaten << "),当前剩余食物" << --nFood << std::endl;
}
else
{
break;
}
}
return 0;
}

unsigned int WINAPI ProductThread(void *pParam)
{
int i = 0;
while (i < 52)
{
std::cout << "生产者进行生产,当前剩余食物" << ++nFood << std::endl;
i++;
}
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hProductThread;
HANDLE hEatThread[THREADCOUNT];

hProductThread = (HANDLE)_beginthreadex(NULL, 0, &ProductThread, (void *)0, 0, 0);
WaitForSingleObject(hProductThread, INFINITE);

for (int i = 0; i < THREADCOUNT
a367
; i++)
{
hEatThread[i] = (HANDLE)_beginthreadex(NULL, 0, &EatThread, (void *)i, 0, 0);
}
WaitForMultipleObjects(THREADCOUNT, hEatThread, TRUE, INFINITE);

::CloseHandle(hProductThread);
for (int i = 0; i < THREADCOUNT; i++)
{
::CloseHandle(hEatThread[i]);
}

system("pause");
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++