Ton*_*ion 9 c++ multithreading mutex memory-model c++11
我正在阅读n3485中定义的C++内存模型,它讨论了发布/获取语义,根据我的理解,以及本博客中给出的定义:
收购语义是可以只适用于该操作的属性读取共享内存,无论是读-修改-写操作或普通负载.然后该操作被认为是读取.获取语义可防止读取采集的内存重新排序,并按程序顺序执行任何读取或写入操作.
发布语义是一种属性,它只能应用于写入共享内存的操作,无论它们是读取 - 修改 - 写入操作还是普通存储.然后将该操作视为写入释放.释放语义通过程序顺序中的任何读取或写入操作来防止写入释放的内存重新排序.
将阻止在当前读/写完成之前或之后重新排序读/写.第一个(获取)将确保当前正在执行的读取不会在其之后的任何读/写重新排序,后者(发布)将确保当前写入未使用之前的读/写操作重新排序它.
现在可以说std::mutex::lock
它将获得语义并且std::mutex::unlock
本质上具有发布语义吗?
在标准中,我可以在部分下找到它
30.4.1.2互斥体类型[thread.mutex.requirements.mutex]
11同步:
unlock()
对同一对象的先前操作应与(1.10)此操作同步.
从我理解的同步并没有在标准中明确定义,但它似乎是在关系看两个不同线程之间评估的两个语句之前发生的类型,但是,根据我对获取/释放语义的理解,这有更多与记忆重新排序有关. 同步也可以称为发布/获取语义?
那么发布/获取语义是否不仅适用于加载/存储操作的重新排序以及操作的线程内交错?
在关于内存模型的标准部分中,它主要讨论了两个线程交错的有序关系.这可以解释这是否也适用于内存排序.
任何人都可以澄清一下吗?
现在可以说std :: mutex :: lock将具有获取语义,并且std :: mutex :: unlock基本上具有发布语义?
是的,这是正确的.
据我所知,同步并未在标准中明确定义
那么,理论上第1.10/8段可能是为了给出与以下内容同步的定义:
某些库调用与另一个线程执行的其他库调用同步.例如,原子存储释放与从存储获取其值的load-acquire 同步(29.3).[注意: ...]
另一方面,这听起来不像是一个非常正式的定义.然而,在第1.10/10段中间接给出了一个更好的,但隐含的更好的:
在评估B if 之前,评估A是依赖性排序的
- A对原子对象M执行释放操作,并且在另一个线程中,B对M执行消耗操作并读取由A标记的释放序列中的任何副作用写入的值,或者
- 对于某些评估X,A在X之前是依赖排序的,而X对B具有依赖性.
[注意:关系"依赖于顺序排序"类似于"与...同步",但使用release/ - 代替释放/获取. - 尾注]
由于" 类似于 "关系通常是对称的,我会说上面的" is-dependency-ordered before "的定义间接提供了" 同步 " 的定义- 尽管你可能正确地反对那些注释是非-normative; 不过,这似乎是预期的定义.
我对与关系同步的直觉是它发生在一个存储某个值的线程执行的写(原子)操作和读取该值的第一个(原子)操作之间.该操作也可能在同一个线程中.
如果两个操作在不同的线程上,则synchronize-with关系在操作上建立跨线程排序.
在标准中,我可以在部分下找到它
30.4.1.2互斥体类型[thread.mutex.requirements.mutex]
11同步:
unlock()
对同一对象的先前操作应与(1.10)此操作同步.
对我来说,这似乎与上面给出的解释兼容.具有释放语义(解锁,存储)的操作将与获取语义(锁定,加载)的操作同步.
但是,根据我对获取/释放语义的理解,这更多地与内存重新排序有关.同步也可以称为发布/获取语义?
释放和获取语义描述了某些操作的本质; 的进行同步-与关系是(确实)一个关系,其已获得或释放语义,在明确定义的方式操作之间建立的.
因此,在某种意义上,synchronize-with是这些操作的语义的结果,我们使用这些语义来实现指令的正确排序并约束CPU或编译器将执行的可能的重新排序.