C++11多线程-原子操作(1)
前面我们讲了C++11下的多线程及相关操作,这些操作在绝大多数情况下应该够用了。但在某些极端场合,如需要高性能的情况下,我们还需要一些更高效的同步手段。本节介绍的原子操作是一种lock free的操作,不需要同步锁,具有很高的性能。在化学中原子不是可分割的最小单位,引申到编程中,原子操作是不可打断的最低粒度操作,是线程安全的。C++11中原子类提供的成员函数都是原子的,是线程安全的。
原子操作中最简单的莫过于atomic_flag,只有两种操作:test and set、clear。我们的原子操作就从这种类型开始。
1. std::atomic_flag
C++11中所有的原子类都是不允许拷贝、不允许Move的,atomic_flag也不例外。atomic_flag顾名思议,提供了标志的管理,标志有三种状态:clear、set和未初始化状态。
1.1 atomic_flag实例化
缺省情况下atomic_flag处于未初始化状态。除非初始化时使用了ATOMIC_FLAG_INIT
宏,则此时atomic_flag处于clear状态。
1.2 std::atomic_flag::clear
调用该函数将会把atomic_flag置为clear状态。clear状态您可以理解为bool类型的false,set状态可理解为true状态。clear函数没有任何返回值:
void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
void clear(memory_order m = memory_order_seq_cst) noexcept;
对于memory_order我们会在后面的章节中详细介绍它,现在先列出其取值及简单释义
序号 | 值 | 意义 |
---|---|---|
1 | memory_order_relaxed | 宽松模型,不对执行顺序做保证 |
2 | memory_order_consume | 当前线程中,满足happens-before原则。 当前线程中该原子的所有后续操作,必须在本条操作完成之后执行 |
3 | memory_order_acquire | 当前线程中,读操作满足happens-before原则。 所有后续的读操作必须在本操作完成后执行 |
4 | memory_order_release | 当前线程中,写操作满足happens-before原则。 所有后续的写操作必须在本操作完成后执行 |
5 | memory_order_acq_rel | 当前线程中,同时满足memory_order_acquire和memory_order_release |
6 | memory_order_seq_cst | 最强约束。全部读写都按顺序执行 |
文章图片
test_and_set是典型的 read-modify-write(RMW)模型,保证多线程环境下只被设置一次。下面代码通过10个线程,模拟了一个计数程序,第一个完成计数的会打印"win"。
#include// atomic_flag
#include // std::cout, std::endl
#include // std::list
#include // std::threadvoid race(std::atomic_flag &af, int id, int n) {
for (int i = 0;
i < n;
i++) {
}
// 第一个完成计数的打印:Win
if (!af.test_and_set()) {
printf("%s[%d] win!!!\n", __FUNCTION__, id);
}
}int main() {
std::atomic_flag af = ATOMIC_FLAG_INIT;
std::list lstThread;
for (int i = 0;
i < 10;
i++) {
lstThread.emplace_back(race, std::ref(af), i + 1, 5000 * 10000);
}for (std::thread &thr : lstThread) {
thr.join();
}return 0;
}
程序输出如下(每次运行,可能率先完成的thread不同):
race[7] win!!!
上一篇 C++11多线程-线程局部存储 |
目录 | 下一篇 C++11多线程-原子操作(2) |
---|
推荐阅读
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 爱就是希望你好好活着
- 昨夜小楼听风
- 知识
- 死结。
- 我从来不做坏事
- 烦恼和幸福
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- Linux下面如何查看tomcat已经使用多少线程
- 说得清,说不清