【发布时间】:2013-03-09 16:48:54
【问题描述】:
我正在阅读 n3485 中定义的 C++ 内存模型,它谈到了释放/获取语义,据我了解,以及 given in this blog 的定义:
获取语义是一个属性,它只能应用于从共享内存中读取的操作,无论它们是读取-修改-写入操作还是普通加载。然后将该操作视为读取-获取。 Acquire 语义防止内存重新排序 read-acquire 在程序顺序之后的任何读或写操作。
释放语义是一个属性,它只能应用于写入到共享内存的操作,无论它们是读-修改-写操作还是普通存储。然后该操作被视为写释放。释放语义防止内存重新排序写入释放与程序顺序之前的任何读取或写入操作。
将防止在当前读/写完成之前或之后重新排序读/写。第一个(获取)将确保当前正在完成的读取不会被任何读/写重新排序,后者(发布)将确保当前写入不会被之前的读/写操作重新排序它。
现在可以说std::mutex::lock 将具有acquire 语义,而std::mutex::unlock 本质上具有release 语义吗?
在标准中,我可以在部分下找到它
30.4.1.2 互斥类型 [thread.mutex.requirements.mutex]
11 同步:对同一对象的先前
unlock()操作应与(1.10)此操作同步。
据我了解 synchronize with 没有在标准中明确定义,但它似乎是一种 发生在 关系的类型,查看两个语句在两个语句之间进行评估但是,根据我对获取/释放语义的理解,不同的线程更多地与内存重新排序有关。 同步也可以称为释放/获取语义?
那么释放/获取语义不仅适用于加载/存储操作的重新排序以及操作的线程内交错吗?
在关于内存模型的标准部分中,它主要讨论的是两个线程交错的有序关系。这对于这是否也适用于内存排序有待解释。
谁能澄清一下?
【问题讨论】:
-
“同步于”在 [intro.multithread], 1.10, 第 8 段中定义。
-
@PeteBecker: 是的,但那里写的内容听起来不像“定义”:“某些库调用与另一个线程执行的其他库调用同步。例如,原子store-release 与从 store (29.3) 中获取其值的 load-acquire 同步。“像“certain”和“for example”这样的词不是很正式。
-
@AndyProwl - 你是对的,它有点模糊。不是因为“确定”,这是说“一些但不是全部”的简短方式,而是因为它并没有完全说明这意味着什么。当库要求说一个操作“与”另一个操作“同步”时,这会引入一种排序,该排序成为“线程间发生之前”关系的一部分。所以没有一个地方正式定义“同步于”。这是一个分布式定义:库规范说明它发生的地方就是它发生的地方。
-
@PeteBecker:我想也许我明白你在说什么,但我不确定这是否使它成为一个“定义”:它只是说明它何时发生,而不是它是什么。现在,这样的外延定义在某些情况下可能是有意义的,但只有内涵定义才具有理解力。我可以说“Foo”是“这个人,这个人,那个人,那个人,那个人”,因为这些都是“Foo”的唯一实例。但是,用这种方式几乎不可能从“Foo”中获得意义。
-
从概念上讲,锁定操作读取解锁互斥体的状态,解锁操作将解锁状态分配给互斥体。
标签: c++ multithreading c++11 mutex memory-model