这会是c中的一个正常工作的自旋锁吗?
Posted
技术标签:
【中文标题】这会是c中的一个正常工作的自旋锁吗?【英文标题】:would this be a functioning spinlock in c? 【发布时间】:2021-09-24 01:44:50 【问题描述】:我目前正在学习操作系统,并且想知道使用这些定义,这会按预期工作还是我错过了一些原子操作?
int locked = 0;
void lsLock()
while(1)
if (locked)
continue;
else
locked = 1;
break;
void lsUnlock()
locked = 0;
提前致谢!
【问题讨论】:
没有。自旋锁实现需要非标准的锁定指令。您需要使用特定于编译器的代码来实现它。你可以先看这里***.com/questions/1383363/… 想象两个线程运行lsLock
函数,它们都以locked == 0
开始执行——它们都检查if (locked)
——它们都看到它为零——它们都锁定它。
@4386427 我忘记了 else 块中的中断。但即使有了它,它也行不通,对吧?
@Flowmotion 不,它不会工作。有几个原因。
【参考方案1】:
第一个问题是编译器假定任何“外部”都不会改变任何东西(除非它被标记为volatile
);这意味着编译器能够对此进行优化:
int locked = 0;
void lsLock()
while(1)
if (locked)
continue;
else
locked = 1;
break;
..进入这个:
int locked = 0;
void lsLock()
if (locked)
while(1)
locked = 1;
显然,如果有其他东西修改 locked
,这将不起作用 - 一旦 while(1)
启动它就不会停止。要解决这个问题,您可以使用volatile int locked = 0;
。
这只防止编译器假设locked
没有改变。没有什么能阻止理论上的 CPU 玩类似的把戏(例如,即使使用 volatile
,非缓存一致的 CPU 也无法实现不同的 CPU 更改 locked
)。为了保证,您需要使用原子或其他东西(例如内存屏障)。
但是;使用volatile int locked
可能会起作用,尤其是对于常见的 80x86 CPU。请注意,“工作”可以被认为是最坏的可能性 - 它导致假设代码很好,然后当您为不同的 CPU 编译相同的代码时会出现壮观的(并且由于时间问题几乎无法调试)灾难。
【讨论】:
以上是关于这会是c中的一个正常工作的自旋锁吗?的主要内容,如果未能解决你的问题,请参考以下文章