我已经在SO上和http://en.wikipedia.org/wiki/Reentrancy_(computing)上阅读了关于重入主题的线索。
我可能会得到可重入函数的想法。但是当我在维基网站上阅读这个例子时,我真的很困惑。
第一个例子:
int t;
void swap(int *x, int *y)
{
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
正如网站所解释的那样:“ 它仍然无法重入,如果在与已经执行swap()的线程相同的上下文中调用isr(),这将继续导致问题。 “=>这可能会发生什么样的问题?交换结果不正确?或者修改了t变量的值?
第二个例子改进了第一个例子:
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);
}
这如何改善第一个?这是否意味着变量t在swap()函数内保持不变?
答案 0 :(得分:1)
重入意味着该函数可以在任何时候中断,并且能够在中断后正确地完成执行,即使在相同的函数被调用一次或多次的情况下也是如此。中断状态。
这里的关键部分是在中断状态下调用的函数的调用必须在恢复原始调用状态之前完成。这是重入和线程安全之间的主要区别:为了保证线程安全,即使在控制返回到原始调用之前中断调用未完成,函数也必须能够继续。
这就是swap
的第二个版本可重入的原因:它在退出时始终保持t
状态不变,因此在中断时进入和退出swap
call不会改变被中断调用所看到的全局状态。