C++11多线程系列主要介绍和讲解现代C++中多线程中内存模型/内存序等相关的知识,后期可能扩展为C++多线程中各个组件相关的内容。
为了完善内存模型相关结构,本篇文章主要讲解release sequence的概念及应用。增加对C++ 内存序的进一步理解。
release sequence 定义关于C++ release sequence定义,可参考如下引用
A release sequence is a subsequence of the modification order of an atomic object. It is headed by a release operation A and followed by an arbitrary number of
• atomic operations performed by the same thread that performed A or
• atomic read-modify-write operations.
关于上述解释,可参考如下理解:
release sequence是针对某一个原子对象而言的修改链,该链以一个release operation为起点,后续元素可由
1. 同一个线程中的原子 *** 作
2. 同一个线程/其他线程中的原子RMW *** 作构成
一个逻辑上的release sequence序列可能会如下表现
release sequence的作用release sequence的作用:简单来说,为了保证release sequence中的后续原子 *** 作与初始化的release operation保持同步于关系,从而产生内存模型所允许的结果以及符合开发者直觉。
release sequence代码示例为了更好的说明release sequence的作用,给出如下代码以供解释,该代码来自《C++ Concurrency in Action》相关章节。
#include#include #include std::vector queue_data; std::atomic count; void wait_for_more_items(); void process(int); void populate_queue() { const unsigned int number_of_items = 20; queue_data.clear(); for (unsigned i = 0; i < number_of_items; ++i) { queue_data.emplace_back(i); } // release sequence初始化点,也即sequence header count.store(number_of_items, std::memory_order_release); } void consume_queue_items() { while (true) { int item_index; // release sequence中的RMW原子操作 if ((item_index = count.fetch_sub(1, std::memory_order_acquire)) <= 0) { wait_for_more_items(); continue; } process(queue_data[item_index-1]); } } int main() { std::thread a(populate_queue); std::thread b(consume_queue_items); std::thread c(consume_queue_items); a.join(); b.join(); c.join(); return 0; }
上述代码可作如下说明:
如果没有release sequence规则,则假设a中release *** 作仅仅同步于b中acquire *** 作,则此时,b可以消费到正确的值,但c会产生data race,因为c中的acquire *** 作并没有同步于a中的release *** 作。
正因为有了release sequence规则,上述代码在多线程下可以正常工作。
关于上述代码可能存在如下release sequence,取自《C++ Concurrency in Action》相关章节,相信如下图中内容,应该可以明白了。
上述实线表示同步于关系,虚线表示release sequence关系。
总结本文中讲解了release sequence的相关定义和使用,完善了相应的C++11多线程 内存序系列文章,后续抽时间会完善C++中fence相关的知识。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)