CE_Mutex包装为同步多线程控制提供了一种相对优雅的方法,它们仍是潜在地易错的,因为开发者有可能会忘记调用release方法(或是由于程序员的疏忽,或是由于C++异常的发生)。为改善应用的健壮性,ACE同步机制有效地利用了C++类构造器和析构器语义。为确保ACE_Mutex锁被自动获取和释放,ACE提供了名为ACE_Guard的助手类,定义如下:ACE_Guard类的对象定义一个代码块,在块开始时获取ACE_Mutex,而在块结束时自动释放。
注意ACE_Guard类被定义为模板,由互斥机制参数化。有若干不同类型的互斥语义[33]。每种互斥共有一个通用接口(也就是,acquire/release),但具有不同的序列化和性能属性。ACE支持的两种互斥是非递归和递归锁。// -*- C++ -*-
//==========================================================================
/**
* @file Null_Mutex.h
*
* $Id: Null_Mutex.h 91626 2010-09-07 10:59:20Z johnnyw $
*
* Moved from Synch.h.
*
* @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//==========================================================================
#ifndef ACE_NULL_MUTEX_H
#define ACE_NULL_MUTEX_H
#include /**/ "ace/pre.h"
#include "ace/os_include/os_errno.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Global_Macros.h"
#include "ace/OS_Memory.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Time_Value;
/**
* @class ACE_Null_Mutex
*
* @brief Implement a do nothing ACE_Mutex, i.e., all the methods are
* no ops.
*/
class ACE_Export ACE_Null_Mutex
{
public:
ACE_Null_Mutex (const ACE_TCHAR * = 0)
: lock_ (0) {}
~ACE_Null_Mutex (void) {}
/// Return 0.
int remove (void) {return 0;}
/// Return 0.
int acquire (void) {return 0;}
/// Return -1 with @c errno == @c ETIME.
int acquire (ACE_Time_Value &) {errno = ETIME; return -1;}
/// Return -1 with @c errno == @c ETIME.
int acquire (ACE_Time_Value *) {errno = ETIME; return -1;}
/// Return 0.
int tryacquire (void) {return 0;}
/// Return 0.
int release (void) {return 0;}
/// Return 0.
int acquire_write (void) {return 0;}
/// Return 0.
int tryacquire_write (void) {return 0;}
/// Return 0.
int tryacquire_write_upgrade (void) {return 0;}
/// Return 0.
int acquire_read (void) {return 0;}
/// Return 0.
int tryacquire_read (void) {return 0;}
/// Dump the state of an object.
void dump (void) const {}
/// Declare the dynamic allocation hooks.
//ACE_ALLOC_HOOK_DECLARE;
int lock_; // A dummy lock.
};
// FUZZ: disable check_for_ACE_Guard
template <class ACE_LOCK>
class ACE_Guard;
/**
* @brief Template specialization of ACE_Guard for the
* ACE_Null_Mutex.
*
* This specialization is useful since it helps to speedup
* performance of the "Null_Mutex" considerably.
*/
template<>
class ACE_Export ACE_Guard<ACE_Null_Mutex>
{
public:
// = Initialization and termination methods.
ACE_Guard (ACE_Null_Mutex &) {}
ACE_Guard (ACE_Null_Mutex &, int) {}
ACE_Guard (ACE_Null_Mutex &, int, int) {}
#if defined (ACE_WIN32)
~ACE_Guard (void) {}
#endif /* ACE_WIN32 */
int acquire (void) { return 0; }
int tryacquire (void) { return 0; }
int release (void) { return 0; }
void disown (void) {}
int locked (void) { return 1; }
int remove (void) { return 0; }
void dump (void) const {}
private:
// Disallow copying and assignment.
ACE_Guard (const ACE_Guard<ACE_Null_Mutex> &);
void operator= (const ACE_Guard<ACE_Null_Mutex> &);
};
template <class ACE_LOCK>
class ACE_Write_Guard;
/**
* @brief Template specialization of ACE_Write_Guard for the
* ACE_Null_Mutex.
*/
template<>
class ACE_Export ACE_Write_Guard<ACE_Null_Mutex>
: public ACE_Guard<ACE_Null_Mutex>
{
public:
ACE_Write_Guard (ACE_Null_Mutex &m)
: ACE_Guard<ACE_Null_Mutex> (m) {}
ACE_Write_Guard (ACE_Null_Mutex &m, int blocked)
: ACE_Guard<ACE_Null_Mutex> (m, blocked) {}
int acquire_write (void) { return 0; }
int acquire (void) { return 0; }
int tryacquire_write (void) { return 0; }
int tryacquire (void) { return 0; }
void dump (void) const {}
};
template <class ACE_LOCK>
class ACE_Read_Guard;
/**
* @brief Template specialization of ACE_Read)Guard for the
* ACE_Null_Mutex.
*/
template<>
class ACE_Export ACE_Read_Guard<ACE_Null_Mutex>
: public ACE_Guard<ACE_Null_Mutex>
{
public:
ACE_Read_Guard (ACE_Null_Mutex &m)
: ACE_Guard<ACE_Null_Mutex> (m) {}
ACE_Read_Guard (ACE_Null_Mutex &m, int blocked)
: ACE_Guard<ACE_Null_Mutex> (m, blocked) {}
int acquire_read (void) { return 0; }
int acquire (void) { return 0; }
int tryacquire_read (void) { return 0; }
int tryacquire (void) { return 0; }
void dump (void) const {}
};
// FUZZ: enable check_for_ACE_Guard
template <class T> class ACE_Malloc_Lock_Adapter_T;
/**
* @brief Template specialization of ACE_Malloc_Lock_Adapter_T for the
* ACE_Null_Mutex.
*/
template<>
class ACE_Export ACE_Malloc_Lock_Adapter_T<ACE_Null_Mutex>
{
public:
ACE_Null_Mutex * operator () (const ACE_TCHAR *name)
{
ACE_Null_Mutex *p;
ACE_NEW_RETURN (p, ACE_Null_Mutex (name), 0);
return p;
}
};
ACE_END_VERSIONED_NAMESPACE_DECL
#include /**/ "ace/post.h"
#endif /* ACE_NULL_MUTEX_H */
与ACE Lock类相比
ACE_Guard的优点:获取了一个锁,他总会释放它,不会因为没有release,而出现线程死锁。
ACE_Guard的缺点:ACE_Guard变量无效时,他才自动调用release。
ACE_Guard类似局部变量,变量无效时,他才会自动调用release。这就出现了一个问题。当在ACE_Guard变量有效时程序出现阻塞,ACE_Guard变量就没有机会自动调用release了,这时死锁就出现了。