web123456

【Linux】Production and consumption model practice ----Ring queue based on semaphore

#pragma once #include <vector> #include <> const int default_cap = 5; template <class T> class RingQueue { public: RingQueue(int max_cap = default_cap) : _rq(max_cap), _max_cap(max_cap), _p_step(0), _c_step(0) { // Semaphore initialization sem_init(&_space_sem, 0, _max_cap); sem_init(&_data_sem, 0, 0); //Initialize the lock pthread_mutex_init(&_c_mtx , nullptr); pthread_mutex_init(&_p_mtx , nullptr); } // Get semaphore void P(sem_t &sp) { sem_wait(&sp); } // Release the semaphore void V(sem_t &sp) { sem_post(&sp); } // Insert operation void Push(const T &t) { // Get the space semaphore -- P(_space_sem); //Critical area lock pthread_mutex_lock(&_p_mtx ); _rq[_p_step] = t; _p_step++; _p_step %= _max_cap; //Unlock pthread_mutex_unlock(&_p_mtx); // Release semaphore ++ V(_data_sem); } // Get the operation void Pop(T *t) { // Get resource semaphore P(_data_sem); pthread_mutex_lock(&_c_mtx); *t = _rq[_c_step]; _c_step++; _c_step %= _max_cap; pthread_mutex_unlock(&_c_mtx); // Release the semaphore V(_space_sem); } ~RingQueue() { // Destroy the corresponding semaphore! sem_destroy(&_space_sem); sem_destroy(&_data_sem); //Release the lock pthread_mutex_destroy(&_c_mtx); pthread_mutex_destroy(&_p_mtx); } private: // The underlying linear structure simulates the ring queue std::vector<T> _rq; // Maximum capacity int _max_cap; // Producer/Consumer Subscript int _p_step; int _c_step; // Space/Resource Semaphore sem_t _space_sem; sem_t _data_sem; // Production/Consumption Lock pthread_mutex_t _p_mtx; pthread_mutex_t _c_mtx; };