led*_*kol 9 language-agnostic synchronization atomic memory-barriers
我需要帮助理解与关系的同步.我读的越多,试图理解的例子,我越觉得我什么都不懂.有时候我觉得这就是它,我已经知道了,但在看了另一个例子之后我再次感到困惑.请帮我把它弄好.
如果A是某个原子变量m的存储,则表示操作A与操作B同步,具有释放语义,B是来自相同变量m的加载,具有获取语义,B读取由A存储的值.还有人说操作A发生在操作B之前
好.如果我们看一下这个例子
thread0执行| thread1执行
商店x(发布)| 加载x(获取)
存储到x这里同步 - 来自x的负载?如果我们确实在这里有同步关系,那么在从x加载之前就存储到x,所以在线程0中存储到x之前排序的所有内容都会发生 - 在从线程1中的x加载之前发生.这意味着这里有强制排序.这样对吗?但在这种情况下,我不明白"和B读取A存储的值"的定义是什么意思?如果线程1比线程0快,则它可以读取旧值.那么这里的关系是什么,是否有任何关系?如果没有,我该如何提供这种关系?
提前致谢.
我不能说我对术语非常熟悉,但这就是我的看法。我将在.NET定义中使用以下术语:“ 如果其他处理器将在任何后续操作的效果之前始终看到其效果,则该操作已获得语义。如果其他处理器将在该操作的效果之前看到每个先前操作的效果,则该操作已释放了语义。本身。 ”
在示例中,存储和加载之间没有强制排序。可以先执行任何一个。当存储操作恰好在加载之前执行时,与B同步。发生这种情况时,保证在执行存储(获取)之前的所有操作(在执行存储(发布)之前的所有操作)。
但是,可以在存储之前执行加载操作。在那种情况下,A不与B同步(因为条件“和B读取由A存储的值”不成立),因此加载之后的操作可以在存储之前的操作之前执行。订单含糊不清。
释放语义保证对于x的某些值,我们将知道在执行存储之前的操作,然后才能在第二个线程中加载相同的存储值(并且在执行加载后的操作之前)。 。
假设count和flag初始化为零,并且两个线程并行运行:
thread0:
st count, 1 (A)
st.release flag, 1 (B)
thread1:
ld.acquire flag (C)
ld count (D)
Run Code Online (Sandbox Code Playgroud)
我们知道A发生在B之前,C发生在D之前,因为它们的顺序受释放的约束并获取语义。B和C的顺序不确定。它仅在B与C同步时才定义,然后我们知道A在D之前发生(因为A在B发生之前在C发生之前在D之前发生。
在线程1中,如果标志为1,则计数始终为1。如果标志为0,则计数可以为0或1。我们可以测试该标志,以确定另一个线程是否已将值设置为该计数。
如果没有获取和释放语义,则可以对装载和存储进行重新排序,并且标记和计数都可以是0或1,而彼此之间没有依赖性。
如果我们想确保B发生在C之前,则可以使用信号量或其他一些等待信号机制。在前面的示例中,我们可以通过等待标志设置来强制执行命令。
thread1:
ld.acquire flag (C)
repeat C while flag == 0
ld count (D)
Run Code Online (Sandbox Code Playgroud)