我正在查看Boost的无锁定队列。
当生产者线程将数据结构T推入缓冲区时,它会(通过复制构造函数)将副本复制到缓冲区中。
当使用者线程试图调用consumer_one()来读取缓冲区中的元素时,似乎需要内存屏障?如果不是,生产者线程所做的更改怎么可能对消费者线程可见?
谢谢!
不需要额外的内存屏障。
当索引按照获取的内存顺序读取,并按照release内存顺序写入时,队列工作正常:http://en.cppreference.com/w/cpp/atomic/memory_order
- 获取:具有此内存顺序的加载操作对受影响的内存位置执行获取操作:执行释放的线程以前对其他内存位置的写入在此线程中可见
- 释放:具有此内存顺序的存储操作执行释放操作:对其他内存位置的先前写入对在同一位置执行消耗或获取的线程可见
正如您所看到的,也不需要担心对实际元素数据的写入,因为索引更新(在复制之后完成)发生在读取之前。
由于使用SPSC队列的文档要求明确指出,使用者和生产者将始终是相同的、单一的线程,因此所有"本地"索引操作都是用"宽松"的内存顺序完成的。
请注意,唯一偏离这一点的操作是reset()
,它类似于构造/销毁,是而不是线程安全的。
关于内存顺序的背景,我推荐Anthony William的优秀著作《C++并发操作》