Linux 多執行緒可重入函式

2021-09-07 07:18:15 字數 1907 閱讀 7803

在單執行緒程式中,整個程式都是順序執行的,乙個函式在同一時刻只能被乙個函式呼叫,但在多執行緒中,由於併發性,乙個函式可能同時被多個函式呼叫,此時這個函式就成了臨界資源,很容易造成呼叫函式處理結果的相互影響,如果乙個函式在多執行緒併發的環境中每次被呼叫產生的結果是不確定的,我們就說這個函式是"不可重入的"/"執行緒不安全"的。為了解決這個問題,posix多執行緒庫提出了一種機制,用來解決多執行緒環境中的執行緒資料私有化問題,這套機制的主要思想是利用同步和互斥維護乙個同名不同值的表,這個表會維護每個執行緒自己的資源位址,表面上是同乙個變數,實質上這個變數在不同的執行緒中的位址是不一樣,這樣就保證了每個執行緒其實都在使用自己的資源,實現了"thread-safe"。

其實,隨著多執行緒程式的逐漸流行,除了這種利用系統機制保護執行緒私有資料的方法,還有一部分人重新編寫了一些多執行緒庫函式,這些函式的主要特點就是實現了演算法和資料的分離,函式內部只負責實現演算法,需要的資料由執行緒傳入,這樣就保證了函式的多執行緒安全,eg

char *asctime(const struct tm *tm);

char *asctime_r(const struct tm *tm, char *buf); //這個就是asctime的thread-safe版,有_r字尾

但由於介面不同,完全重寫的函式推廣尚需時日。

當下用的更多的是使用_reentrant來在原來的函式的基礎上改造,如果編譯的時候定義了這個巨集,相關的庫函式就會被編譯成"thread-safe"的版本。

如果要檢視這些函式的man手冊,可以安裝相關的man手冊

pthread_key_t key           //建立用於保護執行緒私有資源的key

pthread_once_t once_key //建立用於初始化key的once_key,要求用pthread_init_once來賦值,否則結果不確定

pthread_key_create() //建立key

pthread_once() //初始化key

pthread_getspedifc() //從key表中獲得執行緒私有資源的位址

pthread_setspedifc() //將執行緒私有資源的位址放到key中

...

表面上每個函式呼叫了reverse()都會得到rev的位址,其實這個rev位址在不同的執行緒中並不相同,一旦乙個執行緒呼叫了reverse()函式,函式首先會到key標識的表中去搜尋這個執行緒以前是否呼叫過這個函式,如果呼叫過,就將表中屬於這個執行緒的rev位址返回,如果沒有,就分配rev,並將該執行緒和它的專屬rev位址註冊到表中,這樣就把reverse()打造成了乙個可重入的函式。

#include#include#include#includepthread_key_t key;

pthread_once_t once_key=pthread_once_init;

#ifdef _reentrant

void mydestructor(void*p)

void mycreatekey(void)

#endif

char* reverse(char* buf,int len)

#else

static char rev[100];

#endif

bzero(rev,sizeof(rev));

//翻轉buf

while(len--)

rev[len]=*buf++;

return rev;

}void* fcn1(void* p)

}void* fcn2(void* p)

}int main(int argc, const char *argv)

多執行緒之可重入鎖

當乙個執行緒得到物件鎖後,再次請求此物件鎖時是可以再次得到改物件的鎖的 可重入鎖 的概念 自己可以再次獲得自己內部的鎖,比如有一條執行緒獲得了某個物件的鎖,此時這個物件的鎖還沒有釋放,當再次獲取這個物件的鎖的時候還是可以獲取的,如果不可鎖重入的話就會造成死鎖。例如 synchronized和reen...

多執行緒四 可重入鎖

自己可以再次獲取自己的內部鎖。比如有1調執行緒獲得了某個物件的鎖,此時這個物件鎖還沒有釋放,當其再次想要獲取這個物件的鎖的時候還是可以獲取的,如果不可鎖重入的話,就會造成死鎖。可重入鎖也支援在父類繼承的環境中。即子類鎖中呼叫了父類帶鎖函式 普通可重入鎖示例 public class service ...

Linux 執行緒安全和可重入函式

執行緒安全 乙個函式被稱為執行緒安全的 thread safe 當且僅當被多個併發程序反覆呼叫時,它會一直產生正確的結果。如果乙個函式不是執行緒安全的,我們就說它是執行緒不安全的 thread unsafe 我們定義四類 有相交的 執行緒不安全函式。將這類執行緒不安全函式變為執行緒安全的,相對比較容...