asio之静态互斥量
简介
asio设计static_mutex
为了处理静态互斥量,即全局静态互斥量,其针对不同平台有不同的实现
静态互斥量static_mutex
通过条件编译对不同实现定义别名
#if !defined(BOOST_ASIO_HAS_THREADS)
typedef null_static_mutex static_mutex;
# define BOOST_ASIO_STATIC_MUTEX_INIT BOOST_ASIO_NULL_STATIC_MUTEX_INIT
#elif defined(BOOST_ASIO_WINDOWS)
typedef win_static_mutex static_mutex;
# define BOOST_ASIO_STATIC_MUTEX_INIT BOOST_ASIO_WIN_STATIC_MUTEX_INIT
#elif defined(BOOST_ASIO_HAS_PTHREADS)
typedef posix_static_mutex static_mutex;
# define BOOST_ASIO_STATIC_MUTEX_INIT BOOST_ASIO_POSIX_STATIC_MUTEX_INIT
#elif defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
typedef std_static_mutex static_mutex;
# define BOOST_ASIO_STATIC_MUTEX_INIT BOOST_ASIO_STD_STATIC_MUTEX_INIT
#endif
主要包含三个方法
- init
- lock
- unlock
实现
windows平台实现
window平台为win_static_mutex,其定义为
struct win_static_mutex
{typedef boost::asio::detail::scoped_lock<win_static_mutex> scoped_lock;// Initialise the mutex.BOOST_ASIO_DECL void init();// Initialisation must be performed in a separate function to the "public"// init() function since the compiler does not support the use of structured// exceptions and C++ exceptions in the same function.BOOST_ASIO_DECL int do_init();// Lock the mutex.void lock(){::EnterCriticalSection(&crit_section_);}// Unlock the mutex.void unlock(){::LeaveCriticalSection(&crit_section_);}bool initialised_;::CRITICAL_SECTION crit_section_;
};
其初始化是通过创建有名互斥量,来保证只初始化一次
HANDLE mutex = ::CreateMutexW(0, TRUE, mutex_name);
//说明另一个线程已经创建互斥量,等待另一线程初始化完释放互斥量。因为创建成功的线程持有
if (last_error == ERROR_ALREADY_EXISTS) ::WaitForSingleObject(mutex, INFINITE);
//初始化临界区
#if defined(__MINGW32__)// Not sure if MinGW supports structured exception handling, so for now// we'll just call the Windows API and hope.
# if defined(UNDER_CE)::InitializeCriticalSection(&crit_section_);
# elseif (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)){last_error = ::GetLastError();::ReleaseMutex(mutex);::CloseHandle(mutex);return last_error;}
# endif
#else__try{
# if defined(UNDER_CE)::InitializeCriticalSection(&crit_section_);
# elseif (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)){last_error = ::GetLastError();::ReleaseMutex(mutex);::CloseHandle(mutex);return last_error;}
# endif}__except(GetExceptionCode() == STATUS_NO_MEMORY? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH){::ReleaseMutex(mutex);::CloseHandle(mutex);return ERROR_OUTOFMEMORY;}
#endifinitialised_ = true;::ReleaseMutex(mutex);::CloseHandle(mutex);
同时在类中定义有scoped_lock
,用于互斥量的RAII
其静态初始化为
#if defined(UNDER_CE)
# define BOOST_ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0 } }
#else // defined(UNDER_CE)
# define BOOST_ASIO_WIN_STATIC_MUTEX_INIT { false, { 0, 0, 0, 0, 0, 0 } }
#endif // defined(UNDER_CE)
linux平台实现
实现是posix_static_mutex
,其定义为
struct posix_static_mutex
{typedef boost::asio::detail::scoped_lock<posix_static_mutex> scoped_lock;// Initialise the mutex.void init(){// Nothing to do.}// Lock the mutex.void lock(){(void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL.}// Unlock the mutex.void unlock(){(void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL.}::pthread_mutex_t mutex_;
};
//初始化
#define BOOST_ASIO_POSIX_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER }
std标准实现
实现类为std_static_mutex
,定义为
class std_static_mutex: private noncopyable
{
public:typedef boost::asio::detail::scoped_lock<std_static_mutex> scoped_lock;// Constructor.std_static_mutex(int){}// Destructor.~std_static_mutex(){}// Initialise the mutex.void init(){// Nothing to do.}// Lock the mutex.void lock(){mutex_.lock();}// Unlock the mutex.void unlock(){mutex_.unlock();}private:friend class std_event;std::mutex mutex_;
};//初始化
#define BOOST_ASIO_STD_STATIC_MUTEX_INIT 0
空实现
实现类为null_static_mutex
,定义为
struct null_static_mutex
{typedef boost::asio::detail::scoped_lock<null_static_mutex> scoped_lock;// Initialise the mutex.void init(){}// Lock the mutex.void lock(){}// Unlock the mutex.void unlock(){}int unused_;
};
//初始化
#define BOOST_ASIO_NULL_STATIC_MUTEX_INIT { 0 }