2013-05-14 152 views
1

我已经阅读了关于SO上重新进入主题的可能线程以及http://en.wikipedia.org/wiki/Reentrancy_(computing)什么是真正的重入功能?

我可能会得到重入功能的想法。但是当我阅读wiki网站上的例子时,我非常困惑。

第一个例子:

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); 
} 

由于现场解释说:“它仍然无法重入,这将继续造成问题,如果ISR()被调用在相同的情况下作为一个线程已经执行swap()。“=>这里可能会发生什么样的问题?交换结果不正确?或者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()函数内保持不变?

回答

1

重入意味着该功能可以在任何时候中断,并且即使在中断状态下调用同一功能一次或多次时,也能够在中断后正确完成执行。

这里的关键部分是在中断状态下调用的函数的调用必须在原始调用状态恢复之前完成。这是重入性和线程安全性的主要区别:为了线程安全,即使在控制回到原始调用之前中断调用未完成,函数也必须能够继续。

这就是为什么swap的第二个版本是重入:在退出时它总是让t不变的状态,所以在进入和中断调用中退出swap不会改变由中断看到的全局状态调用。

+0

我知道这是旧的,但我也想知道这一点。是否重入代码基本上是指同一个线程。这意味着它只需要确保它不在ISR中调用?否则,同一个线程会自己调用什么呢? – user1876942 2014-12-04 07:17:46

+0

@ user1876942对,重入是一种在ISR存在的情况下推理实现的方式。但是,您并不总是需要中断函数以证明它不可重入。例如,非重入'strtok'被破坏得太多以至于无法在两个嵌套循环中使用它(例如,用'strtok'获得的令牌化令牌)。 – dasblinkenlight 2014-12-04 10:38:18