2013-05-31 44 views
2

考慮由POSIX重入的下面擴展定義:POSIX重入的擴展定義覆蓋線程安全

在POSIX.1c中,「重入函數」被定義爲,其 效果的「功能,當被叫由兩個或多個線程,被保證是彷彿 每個執行的功能相繼在一個 未確定的訂單的線程,即使實際執行是交錯」(ISO/IEC 9945:1-1996,§2.2。 2)。

來源:http://www.unix.org/whitepapers/reentrant.html

由於線程安全的函數不序列化併發執行,因此「線程在一個不確定的順序,分別執行功能此起彼伏,即使實際執行是交錯」也一樣,它是否意味着線程安全函數是可重入的(僅考慮POSIX定義)?

+0

請參閱http://stackoverflow.com/a/2799288/2235132 – devnull

+0

@devnull不,它不考慮POSIX定義 –

+1

我認爲它的關鍵字'interleaved'這使得差異;線程安全部分是順序的或必須是並且不是真正交錯的。只是猜測... – vpram86

回答

2

不,線程安全函數不一定是可重入的。

考慮例如一個由互斥鎖保護的內部狀態的函數,從而使它成爲線程安全的。但是,如果這個函數被調用,呃再次從同一個線程中調用,就會發生死鎖。這種函數的一個常見例子是malloc();例如,malloc是線程安全的,但不能重入,這就是爲什麼你不應該在信號處理程序中調用malloc的原因。

1

線程安全的代碼並不需要序列化併發執行,因爲這個我要說的是線程安全的功能並不需要根據您列舉了POSIX定義爲可重入。

考慮下面的例子。你有兩個線程安全功能:

void inc_count(struct counter* cnt); 
int get_count(struct counter* cnt); 

您可以使用這兩個定義另一個線程安全功能:

inc inc_and_get_count(struct counter* cnt) { 
    inc_count(cnt); 
    return get_count(cnt); 
} 

這樣的功能的合同並不能保證返回值將等於值inc_count()設置,它可以更大,但該函數仍然是線程安全的。

但它不能重返進入,根據定義,從兩個不同的線程兩次調用該函數可以返回相同的值,這將永遠是如果處決序列的情況。

1

否重入和線程安全是函數的正交性。可重入函數的POSIX.1c定義並不意味着線程安全,因爲函數可能是可重入的,線程安全的,兩者都不是。重入函數只保證調用不會通過修改其他調用所依賴的狀態而相互干擾,而不是那些調用必須是線程安全的。