What is the best practice for passing data between threads? Queues, messages or others?

前端 未结 1 1317
梦谈多话
梦谈多话 2021-02-04 17:39

I got sensor data of various types that needs to be processed at different stages. From what I have read around, the most efficent way is to split the tasks into threads. Each p

1条回答
  •  离开以前
    2021-02-04 18:35

    I had to do something similar recently. I used the approach of input/output queue. I think is the best and fast method to use. This is my version of a thread safe concurrent queue. I have in my project three working threads doing lots of calculation in sequence to the same buffer etc. Each thread use the pop from the input queue and push the output queue. So I have this wpop that wait the next buffer available in the queue. I hope can be usefull for you.

    /*
        Thread_safe queue with conditional variable
    */
    
    template
    class CConcurrentQueue
    {
    private:
        /// Queue
        std::queue m_queue;       
        /// Mutex to controll multiple access
        std::mutex m_mutex;                 
        /// Conditional variable used to fire event
        std::condition_variable m_cv;       
        /// Atomic variable used to terminate immediately wpop and wtpop functions
        std::atomic m_forceExit = false;  
    
    public:
        ///  Add a new element in the queue. 
        ///  New element. 
        void push ( dataType const& data )
        {
            m_forceExit.store ( false );
            std::unique_lock lk ( m_mutex );
            m_queue.push ( data );
            lk.unlock ();
            m_cv.notify_one ();
        }
        ///  Check queue empty. 
        ///  True if the queue is empty. 
        bool isEmpty () const
        {
            std::unique_lock lk ( m_mutex );
            return m_queue.empty ();
        }
        ///  Pop element from queue. 
        ///  [in,out] Element. 
        ///  false if the queue is empty. 
        bool pop ( dataType& popped_value )
        {
            std::unique_lock lk ( m_mutex );
            if ( m_queue.empty () )
            {
                return false;
            }
            else
            {
                popped_value = m_queue.front ();
                m_queue.pop ();
                return true;
            }
        }
        ///  Wait and pop an element in the queue. 
        ///  [in,out] Element. 
        ///   False for forced exit. 
        bool wpop ( dataType& popped_value )
        {
            std::unique_lock lk ( m_mutex );
            m_cv.wait ( lk, [&]()->bool{ return !m_queue.empty () || m_forceExit.load(); } );
            if ( m_forceExit.load() ) return false;
            popped_value = m_queue.front ();
            m_queue.pop ();
            return true;
        }
        ///  Timed wait and pop an element in the queue. 
        ///  [in,out] Element. 
        ///  [in] Wait time. 
        ///   False for timeout or forced exit. 
        bool wtpop ( dataType& popped_value , long milliseconds = 1000)
        {
            std::unique_lock lk ( m_mutex );
            m_cv.wait_for ( lk, std::chrono::milliseconds ( milliseconds  ), [&]()->bool{ return !m_queue.empty () || m_forceExit.load(); } );
            if ( m_forceExit.load() ) return false;
            if ( m_queue.empty () ) return false;
            popped_value = m_queue.front ();
            m_queue.pop ();
            return true;
        }
        ///  Queue size.     
        int size ()
        {   
            std::unique_lock lk ( m_mutex );
            return static_cast< int >( m_queue.size () );
        }
        ///  Free the queue and force stop. 
        void clear ()
        { 
            m_forceExit.store( true );
            std::unique_lock lk ( m_mutex );
            while ( !m_queue.empty () )
            {
                delete m_queue.front ();
                m_queue.pop ();
            }
        }
        ///  Check queue in forced exit state. 
        bool isExit () const
        {
            return m_forceExit.load();
        }
    
    };
    

    0 讨论(0)
提交回复
热议问题