跨平台中对于 条件量(condition) 的包装

来源:互联网 发布:breed改mac 编辑:程序博客网 时间:2024/05/01 17:39

说明:

  1. 条件量(Condition)用于多线程同步,一个条件量常常与一个锁(windows下是临界区,linux下是pthread_mutex_t)同时使用
  2. 跨平台宏(platform.hpp)的定义参见另一篇博文,当然截取代码实现时可以换成自己习惯的定义。跨平台中条件编译的使用使得其实现代码不是那么容易阅读,但是在使用这个包装类的时候就比较容易阅读了
  3. 与条件量配合使用的锁类型 (跨平台代码中用 Condition::condition_lock_type 来使用),定义在另外两篇博文中spinlock 和 mutex
/** * @file - * @author jingqi * @date 2010-07-09 */#ifndef ___HEADFILE___B926495D_967A_45A2_8F56_4FFB10F2E34B_#define ___HEADFILE___B926495D_967A_45A2_8F56_4FFB10F2E34B_#include <nut/platform/platform.hpp>#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)#   include <windows.h>#   include "spinlock.hpp"#else#   include <pthread.h>#endif#include "mutex.hpp"namespace nut{class Condition{#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)    CONDITION_VARIABLE m_cond;#else    pthread_cond_t m_cond;#endifpublic:#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)    typedef SpinLock condition_lock_type; // windows 下condition只能配合临界区#else    typedef Mutex condition_lock_type;#endif    Condition()    {#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        ::InitializeConditionVariable(&m_cond);#else        int rs = pthread_cond_init(&m_cond, NULL);        assert(0 == rs);#endif    }    ~Condition()    {#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        /* no need to destroy in windows */#else        int rs = pthread_cond_destroy(&m_cond);        assert(0 == rs);#endif    }    bool signal()    {#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        ::WakeConditionVariable(&m_cond);        return true;#else        return 0 == pthread_cond_signal(&m_cond);#endif    }    bool broadcast()    {#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        ::WakeAllConditionVariable(&m_cond);        return true;#else        return 0 == pthread_cond_broadcast(&m_cond);#endif    }    /**     * release lock, wait for signal or interrupt, lock and wake     */    bool wait(condition_lock_type *mutex)    {        assert(NULL != mutex);#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        return TRUE == ::SleepConditionVariableCS(&m_cond, mutex->innerMutex(), INFINITE);#else        return 0 == pthread_cond_wait(&m_cond, mutex->innerMutex());#endif    }    /**     * work the same as above     */    bool timedwait(condition_lock_type *mutex, unsigned s, unsigned ms = 0)    {        assert(NULL != mutex);#if defined(NUT_PLATFORM_OS_WINDOWS) && !defined(NUT_PLATFORM_CC_MINGW)        DWORD dwMilliseconds = s * 1000 + ms;        return TRUE == ::SleepConditionVariableCS(&m_cond, mutex->innerMutex(), dwMilliseconds);#else        struct timespec abstime;#   if defined(NUT_PLATFORM_OS_WINDOWS) && defined(NUT_PLATFORM_CC_MINGW)        Mutex::clock_getrealtime(&abstime);#   else        clock_gettime(CLOCK_REALTIME, &abstime);#   endif        abstime.tv_sec += s;        abstime.tv_nsec += ((long)ms) * 1000 * 1000;        return 0 == pthread_cond_timedwait(&m_cond, mutex->innerMutex(), &abstime);#endif    }};}#endif /* head file guarder */


原创粉丝点击