我正在阅读在C++中定义的n3485内存模型,它讨论的是发布/获取语义,这是根据我所理解的,也是从定义在这个博客里。
获取语义是一个属性,它只能应用于从共享内存读取的操作,无论它们是读-修改-写操作还是普通加载。然后,该操作被认为是读取-获取。获取语义,防止对读-获取的内存重新排序,并按照程序顺序执行任何读或写操作。 发布语义是一个属性,它只适用于将写入共享内存的操作,无论它们是读-修改-写入操作还是普通存储。然后,该操作被认为是一个写版本。发布语义防止使用任何按程序顺序在其前面的读或写操作对写发布进行内存重新排序。
将防止在当前进行读/写之前或之后重新排序读/写。第一个(获取)将确保当前正在进行的读取不会被重新排序,之后会出现任何读/写,后者(版本)将确保当前的写入不会与前面的读/写操作重新排序。
现在可以说std::mutex::lock将获得语义,而std::mutex::unlock本质上具有发布语义吗?
在“标准”中,我可以在以下部分找到这个
thread.mutex.requirements.mutex类型30.4.1.2
11同步:同一对象上先前的
unlock()操作应与(1.10)此操作同步。
据我所理解,在标准中没有明确地定义同步,然而,在查看两个不同线程之间的两个语句的关系之前,这似乎是一种情况,然而,根据我对获取/发布语义的理解,这更多地与内存重新排序有关。同步是否也可以称为发布/获取语义?
那么,发布/获取语义是否不仅适用于加载/存储操作的重新排序,也适用于操作的线程内交织?
在关于内存模型的标准部分中,它主要以两个线程交织的形式讨论有序关系。这就为解释这是否也适用于内存排序留下了余地。
有人能澄清吗?
发布于 2013-03-09 17:50:59
现在可以说std::mutex::lock将获得语义,而std::mutex::unlock本质上具有发布语义?
是的,,这是正确的。
据我所理解,在标准中没有显式地定义同步。
理论上,第1.10/8段可能是为了给出同步的定义
某些库调用与另一个线程执行的其他库调用同步。例如,原子存储释放与从存储(29.3)获取其值的负载获取同步。注:.
另一方面,这听起来不像是一个非常正式的定义。然而,第1.10/10段间接地给出了一个更好的,尽管是隐含的:
求值A是在计算B之前排序的,如果 - A对原子对象M执行释放操作,在另一个线程中,B对M执行消耗操作,并读取由A领导的释放序列中任何副作用所写的值,或 -对于某些求值X,A是依赖关系--在X和X带依赖项B之前排序。 注:的关系“是依赖-排序前”类似于“同步与”,但使用释放/消费代替发布/获取.-end注释
由于“是类似于”的关系通常是对称的,我想说,上面关于"is -依赖-之前排序“的定义也间接地提供了”同步“的定义--尽管您可能正确地反对注释是非规范性的;不过,这似乎是预定的定义。
我对关系同步的直觉是,它发生在存储某个值的线程执行的写(原子)操作和读取该值的第一个(原子)操作之间。该操作也可能处于同一线程中。
如果这两个操作位于不同的线程上,那么同步-with关系将建立对操作的跨线程排序。
在“标准”中,我可以在以下部分找到这个 thread.mutex.requirements.mutex类型30.4.1.2 11同步:同一对象上先前的
unlock()操作应与(1.10)此操作同步。
在我看来,这似乎符合上述解释。具有释放语义(解锁、存储)的操作将与获取语义(锁、加载)的操作同步。
然而,根据我对获取/发布语义的理解,这更多地与内存重新排序有关。同步是否也可以称为发布/获取语义?
发布和获取语义描述了某些操作的性质;同步-与关系(确实)是在具有或发布语义的操作之间以一种定义良好的方式建立的关系。
因此,从某种意义上说,同步是这些操作的语义的结果,我们使用这些语义来实现指令的正确排序,并限制CPU或编译器执行的可能的重新排序。
https://stackoverflow.com/questions/15313296
复制相似问题