队列<T>上的原子操作?
Posted
技术标签:
【中文标题】队列<T>上的原子操作?【英文标题】:Atomic operation on queue<T>? 【发布时间】:2015-08-26 12:57:53 【问题描述】:我应该在 Visual C++ 中实现一个带有队列的类;在这个队列中我要做原子操作。在网上搜索,我找到了 std::atomic 类,但我保留了一些问题。第一个是:有什么区别:
A)atomic <queue <T>> fifo;
B)queue <atomic <T>> fifo;
?
第二个问题是:如何进行push这样的原子操作?
push (T.load)
是正确的解决方案吗?
最后一个问题是:如果我用互斥锁保护队列上的某些操作,我还需要对其进行原子操作吗?
感谢您的任何建议,问候
【问题讨论】:
您究竟需要什么样的雾化?什么需要是原子? 编写正确的原子队列非常困难。世界级的专家在这方面失败了。你知道你是否有单一的生产者 - 单一的消费者吗?单个生产者 - 多个消费者?多个生产者 - 单个消费者?多个生产者 - 多个消费者?这些是具有不同要求的不同案例。 当你说原子时,我想到了无锁。如果您只是在pop
和 push
函数的开头获得一个互斥锁,那么您应该很好。
在 Windows 上,您可以使用 PPL 标头和 concurrent_* 容器来实现线程安全的标准库。
在你的上下文中,原子可能意味着“队列上的操作是不可分割的”——队列上的事情可以在给定的原子操作之前或之后发生,但不能重叠或发生在中间。
【参考方案1】:
A) atomic<queue <T>> fifo;
甚至不会编译,因为 std::atomic
需要一个可简单复制的类型
B) 将执行 T 类型的原子读取或写入,但使用队列(推送或弹出)的操作将不是原子的。
您需要使用mutex
保护queue
操作:
template<typename T>
class my_queue
public:
void push( const T& value )
std::lock_guard<std::mutex> lock(m_mutex);
m_queque.push(value);
void pop()
std::lock_guard<std::mutex> lock(m_mutex);
m_queque.pop();
private:
std::queue<T> m_queque;
mutable std::mutex m_mutex;
;
【讨论】:
感谢您的回答。所以,在您看来,“插入和删除操作应该是原子的”这句话与“用互斥锁保护操作”是一样的吗? 如果你用互斥锁保护操作,操作将是原子的。在我的答案中添加了一个示例类。以上是关于队列<T>上的原子操作?的主要内容,如果未能解决你的问题,请参考以下文章