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

标签 c++ unit-testing countdownlatch

我尝试使用增强互斥体和条件变量来实现 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;           
    };

最佳答案

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

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

您可以对 AtomicCounter 使用相同的基本思想。

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

关于c++ - C++ 中的 CountDownLatch 使用 Boost Mutexes 和 Condition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5825565/

相关文章:

unit-testing - 有 xUnit++ 的文档吗

Java CountDownLatch thread.run() 倒计时latch 获取异常时等待超时值

java - CountDownLatch 在计数到零时不停止

c# - 将模拟对象与字典一起使用

java - 将一个线程置于 sleep 状态,直到另一个线程中的条件得到解决

c++ - 在新数组中存储字符数组地址

c++ - 从直方图中获取颜色 vector maxValue

c++ - while循环中的while循环,两个条件如何工作?

c++ - 触摸板 + QToolButton = supperios press

ruby-on-rails - 为什么我需要使用 minitest/autorun?