2013-05-14 154 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