我曾经认为所有可重入函数都是线程安全的。但我读了Reentrancy page in Wiki ,它发布的代码“完全可重入,但不是线程安全的。因为它不能确保全局数据在执行期间处于一致状态”
int t;
void swap(int *x, int *y)
{
int s;
s = t; // save global variable
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
我不明白它的解释。为什么这个函数不是线程安全的?是不是因为全局变量int t
会在线程执行过程中发生变化?
最佳答案
这种类型的重入的诀窍在于,在执行第二个调用时,第一个调用的执行停止。就像子函数调用一样。在第二个调用完全结束后,第一个调用继续。因为该函数在进入时保存 t 的状态并在退出时恢复它,所以当它继续时第一次调用没有任何改变。因此,无论第一个调用在何处中断,您始终有一个明确且严格的执行顺序。
当此函数在多个线程中运行时,所有执行都是并行完成的,即使是在多核 CPU 中也是真正的并行。所有线程都没有定义的执行顺序,仅在单个线程内。因此,其他线程之一可以随时更改 t 的值。
关于c - 为什么这段代码可重入但不是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9116598/