C ++中的CountDownLatch使用Boost Mutexes和Condition

时间:2011-04-28 22:01:14

标签: c++ unit-testing countdownlatch

我尝试使用boost互斥锁和条件变量来实现CountDownLatch。下面是代码,想知道我是否需要添加其他内容。

我如何对这段代码进行单元测试?

template< class TypeVal >
    class AtomicCounter
    {
    public:
        AtomicCounter( TypeVal val ) : m_typeVal( val ) 
        {
        }

        AtomicCounter() : m_typeVal(0)
        {
        }

        AtomicCounter(const AtomicCounter& cpy) : m_typeVal(cpy.m_typeVal)
        {   
            boost::mutex::scoped_lock scoped_lock(cpy.m_atomicMutex);
            m_typeVal = cpy.m_typeVal;
        }

        const AtomicCounter& operator=(const AtomicCounter& other)
        {
           if (this == &other)
              return *this;
           boost::mutex::scoped_lock lock1(&m_atomicMutex < &other.m_atomicMutex ? m_atomicMutex : other.m_atomicMutex);
           boost::mutex::scoped_lock lock2(&m_atomicMutex > &other.m_atomicMutex ? m_atomicMutex : other.m_atomicMutex);
           m_typeVal = other.m_typeVal;
           return *this;
        }

        virtual ~AtomicCounter() 
        {
        }

        const TypeVal& getCount() const
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            return m_typeVal; 
        }

        const TypeVal& setCount( const TypeVal &val ) 
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            m_typeVal = val; 
            return m_typeVal; 
        }

        const TypeVal& increment() 
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            m_typeVal++ ; 
            return m_typeVal; 
        }

        const TypeVal& decrement() 
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            m_typeVal-- ; 
            return m_typeVal; 
        }

        const TypeVal& increment(const TypeVal& t) 
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            m_typeVal+=t ; 
            return m_typeVal; 
        }

        const TypeVal& decrement(const TypeVal& t) 
        { 
            boost::mutex::scoped_lock lock( m_atomicMutex ); 
            m_typeVal-=t ; 
            return m_typeVal; 
        }


    private:
        mutable boost::mutex m_atomicMutex;
        TypeVal m_typeVal;
    };

           class CountDownLatch
    {
    public:
        CountDownLatch( int count ): m_cdlCount( count ) 
        {
        }

        CountDownLatch(const CountDownLatch& cpy)
        {
             boost::unique_lock<boost::mutex>::unique_lock(const_cast<boost::mutex&>(cpy.m_cdlMutex));
            m_cdlCount = cpy.m_cdlCount;
        }

        const CountDownLatch& operator=(const CountDownLatch& other)
        {
           if (this == &other)
              return *this;
           boost::mutex::scoped_lock lock1(const_cast<boost::mutex&>(&m_cdlMutex < &other.m_cdlMutex ? m_cdlMutex : other.m_cdlMutex));
           boost::mutex::scoped_lock lock2(const_cast<boost::mutex&>(&m_cdlMutex > &other.m_cdlMutex ? m_cdlMutex : other.m_cdlMutex));
           m_cdlCount = other.m_cdlCount;
           return *this;
        }

        virtual ~CountDownLatch() 
        {
        }
        void wait() 
        { 
            boost::mutex::scoped_lock lock( m_cdlMutex ); 
            if( m_cdlCount.getCount() > 0 ) 
            { 
                m_cdlCondition.wait( lock ); 
            } 
        }
        void wait( uint64_t timeoutMicros ) 
        { 
            boost::mutex::scoped_lock lock( m_cdlMutex ); 
            if( m_cdlCount.getCount() > 0 ) 
            {
                boost::posix_time::time_duration td = boost::posix_time::milliseconds( timeoutMicros ); 
                m_cdlCondition.timed_wait( lock, td ); 
            } 
        }
        void countDown() 
        {  
            boost::mutex::scoped_lock lock( m_cdlMutex ); 
            if( m_cdlCount.decrement() == 0 ) 
            { 
                m_cdlCondition.notify_all(); 
            } 
        }

        int getCount()
        {
            return m_cdlCount.getCount();
        }


    private:
        boost::mutex m_cdlMutex;
        boost::condition_variable m_cdlCondition;
        AtomicCounter< int >  m_cdlCount;           
    };

1 个答案:

答案 0 :(得分:1)

对于单元测试,您可以尝试压力测试。例如,对于CountDownLatch,创建25个同时调用CountDownLatch::countDown()的测试线程,25个同时调用CountDownLatch::getCount()的其他线程,以及25个调用CountDownLatch::wait()的其他线程。为了使事情更加同步,使用屏障,或让线程睡眠到相同的绝对时间。通过连接所有线程,确保所有线程正确终止(没有死锁)。确保CountDownLatch::m_cdlCount最终为零。

多次运行相同的测试(合理的时间)。

您可以对AtomicCounter使用相同的基本概念。

可能还有其他测试多头代码的技术,但这是我最熟悉的。