Implementing boost::barrier in C++11

前端 未结 3 1923
太阳男子
太阳男子 2020-12-08 21:32

I\'ve been trying to get a project rid of every boost reference and switch to pure C++11.

At one point, thread workers are created which wait for a barrier to give t

相关标签:
3条回答
  • 2020-12-08 22:15

    Use a std::condition_variable instead of a std::mutex to block all threads until the last one reaches the barrier.

    class Barrier
    {
    private:
        std::mutex _mutex;
        std::condition_variable _cv;
        std::size_t _count;
    public:
        explicit Barrier(std::size_t count) : _count(count) { }
        void Wait()
        {
            std::unique_lock<std::mutex> lock(_mutex);
            if (--_count == 0) {
                _cv.notify_all();
            } else {
                _cv.wait(lock, [this] { return _count == 0; });
            }
        }
    };
    
    0 讨论(0)
  • 2020-12-08 22:18

    Here's my version of the accepted answer above with Auto reset behavior for repetitive use; this was achieved by counting up and down alternately.

        /**
        * @brief Represents a CPU thread barrier
        * @note The barrier automatically resets after all threads are synced
        */
        class Barrier
        {
        private:
            std::mutex m_mutex;
            std::condition_variable m_cv;
    
            size_t m_count;
            const size_t m_initial;
    
            enum State : unsigned char {
                Up, Down
            };
            State m_state;
    
        public:
            explicit Barrier(std::size_t count) : m_count{ count }, m_initial{ count }, m_state{ State::Down } { }
    
            /// Blocks until all N threads reach here
            void Sync()
            {
                std::unique_lock<std::mutex> lock{ m_mutex };
    
                if (m_state == State::Down)
                {
                    // Counting down the number of syncing threads
                    if (--m_count == 0) {
                        m_state = State::Up;
                        m_cv.notify_all();
                    }
                    else {
                        m_cv.wait(lock, [this] { return m_state == State::Up; });
                    }
                }
    
                else // (m_state == State::Up)
                {
                    // Counting back up for Auto reset
                    if (++m_count == m_initial) {
                        m_state = State::Down;
                        m_cv.notify_all();
                    }
                    else {
                        m_cv.wait(lock, [this] { return m_state == State::Down; });
                    }
                }
            }
        };  
    
    0 讨论(0)
  • 2020-12-08 22:23
    class Barrier {
    public:
        explicit Barrier(std::size_t iCount) : 
          mThreshold(iCount), 
          mCount(iCount), 
          mGeneration(0) {
        }
    
        void Wait() {
            std::unique_lock<std::mutex> lLock{mMutex};
            auto lGen = mGeneration;
            if (!--mCount) {
                mGeneration++;
                mCount = mThreshold;
                mCond.notify_all();
            } else {
                mCond.wait(lLock, [this, lGen] { return lGen != mGeneration; });
            }
        }
    
    private:
        std::mutex mMutex;
        std::condition_variable mCond;
        std::size_t mThreshold;
        std::size_t mCount;
        std::size_t mGeneration;
    };
    
    0 讨论(0)
提交回复
热议问题