#ifndef __TC_CAS_QUEUE_H_ #define __TC_CAS_QUEUE_H_ #include #include #include #include "util/tc_lock.h" #include "util/tc_spin_lock.h" using namespace std; namespace tars { ///////////////////////////////////////////////// /** * @file tc_cas_queue.h * @brief No Lock Threads * @brief 线程无锁 * * * @author ruanshudong@qq.com */ ///////////////////////////////////////////////// /** * @brief 线程安全队列 */ template > class TC_CasQueue { public: TC_CasQueue():_size(0){}; public: typedef D queue_type; /** * @brief Get data from the head, if there's no data, throw exception. * @brief 从头部获取数据, 没有数据抛异常 * * @param t * * @return bool:true-> get data successfully, false-> no data * @return bool: true, 获取了数据, false, 无数据 */ T front(); /** * @brief 从头部获取数据 * * @param t * * @return bool:true-> get data successfully, false-> no data * @return bool: true, 获取了数据, false, 无数据 */ bool pop_front(T& t); /** * @brief Get data from the head * @brief 从头部获取数据 * * @return bool:true-> get data successfully, false-> no data * @return bool: true, 获取了数据, false, 无数据 */ bool pop_front(); /** * @brief Set data at the bottom of the queue * @brief 放数据到队列后端. * * @param t */ void push_back(const T& t); /** * @brief * @brief 放数据到队列后端. * * @param vt */ void push_back(const queue_type &qt); /** * @brief 放数据到队列前端. * * @param t */ void push_front(const T& t); /** * @brief 放数据到队列前端. * * @param vt */ void push_front(const queue_type &qt); /** * @brief 交换数据 * * @param q * @return 有数据返回true, 无数据返回false */ bool swap(queue_type &q); /** * @brief 队列大小. * * @return size_t 队列大小 */ size_t size() const; /** * @brief 清空队列 */ void clear(); /** * @brief 是否数据为空. * * @return bool 为空返回true,否则返回false */ bool empty() const; protected: TC_CasQueue(const TC_CasQueue&) = delete; TC_CasQueue(TC_CasQueue&&) = delete; TC_CasQueue& operator=(const TC_CasQueue&) = delete; TC_CasQueue& operator=(TC_CasQueue&&) = delete; protected: /** * 队列 */ queue_type _queue; /** * 队列长度 */ size_t _size; //锁 TC_SpinLock _mutex; }; template T TC_CasQueue::front() { TC_LockT lock (_mutex); return _queue.front(); } template bool TC_CasQueue::pop_front(T& t) { TC_LockT lock (_mutex); if (_queue.empty()) { return false; } t = _queue.front(); _queue.pop_front(); assert(_size > 0); --_size; return true; } template bool TC_CasQueue::pop_front() { TC_LockT lock (_mutex); if (_queue.empty()) { return false; } _queue.pop_front(); assert(_size > 0); --_size; return true; } template void TC_CasQueue::push_back(const T& t) { TC_LockT lock (_mutex); _queue.push_back(t); ++_size; } template void TC_CasQueue::push_back(const queue_type &qt) { TC_LockT lock (_mutex); typename queue_type::const_iterator it = qt.begin(); typename queue_type::const_iterator itEnd = qt.end(); while (it != itEnd) { _queue.push_back(*it); ++it; ++_size; } } template void TC_CasQueue::push_front(const T& t) { TC_LockT lock (_mutex); _queue.push_front(t); ++_size; } template void TC_CasQueue::push_front(const queue_type &qt) { TC_LockT lock (_mutex); typename queue_type::const_iterator it = qt.begin(); typename queue_type::const_iterator itEnd = qt.end(); while (it != itEnd) { _queue.push_front(*it); ++it; ++_size; } } template bool TC_CasQueue::swap(queue_type &q) { TC_LockT lock (_mutex); if (_queue.empty()) { return false; } q.swap(_queue); _size = _queue.size(); return true; } template size_t TC_CasQueue::size() const { TC_LockT lock(_mutex); return _size; } template void TC_CasQueue::clear() { TC_LockT lock(_mutex); _queue.clear(); _size = 0; } template bool TC_CasQueue::empty() const { TC_LockT lock(_mutex); return _queue.empty(); } } #endif