- 论坛徽章:
- 9
|
本帖最后由 wlmqgzm 于 2016-11-05 20:23 编辑
回复 3# VIP_fuck
问题一: 4 这一行有可能在 1 2 3 之前执行吗?
答复: 是的, 4 这一行有可能在3 之前执行, 现代CPU都是乱序执行的, 无法确定实际执行的顺序.
第二个问题,假如一个原子变量 count,线程 A 是 store(),线程 B 是load() 操作,那么线程 A 如果指定 store(memory_order_release) ,线程 B 指定 load(memory_order_acquire),这样的话,一定是 A 的store 发生在 B 的 load() 之前吗?
答复: A 的store 不一定是发生在 B 的 load() 之前,
store(memory_order_release) 保证的是在此store之前的store全部执行完毕了, 线程 B 指定 load(memory_order_acquire)保证的是在此之后的load指令不允许提前执行.
我们利用这个参数实现 无锁设计方法: memory_order_release/acquire就是对于保证struct数据的完整性, 相当于实现了读写struct的原子性的操作.
读线程B load(memory_order_acquire) 获得当前的 对象裸指针T*, 然后开始读T对象, load(memory_order_acquire) 保证的是取到的数据一定是完整的数据, 避免发生数据乱序执行,( 避免这样的情况: 例如:先读了旧数据,再获得新的对象裸指针T*, 继续读数据, 这样一半新数据, 一半旧数据的情况 )
写线程A 新生成 一个 对象裸指针T* new, 旧对象Copy change, store(memory_order_release) 更新裸指针T* , 保证的是在此store之前的store全部执行完毕了, 保证 struct数据的完整的store了,
当然仅仅这样还不够实现无锁并发, 还要实现一个 垃圾内存自动回收机制, 否则部分线程读旧数据, 部分线程读新数据, 写线程如果直接回收内存, 那么部分读线程可能会崩溃或者出现离奇的错误.
|
|