在整個文件中,術語「可重入」和「執行緒安全」用於標記類和函式,以指示它們如何在多執行緒應用程式中使用:
因此,執行緒安全函式始終是可重入的,但可重入函式並非始終是執行緒安全的。
通過擴充套件,如果可以從多個執行緒安全地呼叫其成員函式,則該類稱為可重入的,只要每個執行緒使用該類的不同例項即可。 如果可以從多個執行緒安全地呼叫其成員函式,則該類是執行緒安全的,即使所有執行緒都使用該類的相同例項也是如此。
注意
:如果打算將qt類用於多個執行緒,則僅將它們記錄為執行緒安全的。 如果某個函式未標記為執行緒安全或可重入,則不應在其他執行緒中使用該函式。 如果某個類未標記為執行緒安全或可重入,則不應從其他執行緒訪問該類的特定例項。
c ++類通常是可重入的,僅因為它們僅訪問自己的成員資料。 只要沒有其他執行緒可以同時在該類的同一例項上呼叫成員函式,則任何執行緒都可以在可重入類的例項上呼叫成員函式。 例如,下面的counter類是可重入的:
class
counter
void
increment()
void
decrement()
intvalue()
const
private
:int n;
};
該類不是執行緒安全的,因為如果多個執行緒嘗試修改資料成員n,則結果是不確定的。 這是因為++和-運算子並不總是原子的。 實際上,它們通常擴充套件為三個機器指令:
將變數的值載入到暫存器中。
1、遞增或遞減暫存器的值。
2、將暫存器的值儲存回主儲存器。
3、如果執行緒a和執行緒b同時載入變數的舊值,增加它們的暫存器並儲存回去,它們最終將互相覆蓋,並且變數僅增加一次!
顯然,訪問必須序列化:執行緒a必須執行1、2、3步驟(在原子上不中斷),執行緒b才能執行相同的步驟; 或相反亦然。 使類成為執行緒安全的一種簡單方法是使用qmutex保護對資料成員的所有訪問:
class
counter
void
increment()
void
decrement()
intvalue()
const
private
:mutable qmutex mutex;
int n;
};
qmutexlocker類自動將互斥鎖鎖定在其建構函式中,並在函式結束時在呼叫析構函式時將其解鎖。 鎖定互斥鎖可確保對來自不同執行緒的訪問進行序列化。 互斥鎖資料成員使用mutable
宣告,因為我們需要在value()中鎖定和解鎖互斥鎖,這是乙個const函式。
許多qt類是可重入的,但它們不是執行緒安全的,因為使它們成為執行緒安全的會導致反覆鎖定和解鎖qmutex的額外開銷。 例如,qstring是可重入的,但不是執行緒安全的。 您可以安全地同時從多個執行緒訪問qstring的不同例項,但是不能安全地同時從多個執行緒訪問qstring的同一例項(除非您用qmutex保護自己的訪問)。
注意:多執行緒域中的術語尚未完全標準化。 posix使用可重入和執行緒安全的定義,這些定義對其c api有所不同。 當將其他物件導向的c ++類庫與qt一起使用時,請確保了解定義。
可重入和執行緒安全
執行緒安全這個詞對我來說已經不是很陌生的了,但是遇到乙個叫做可重入函式的詞,它給我的感覺和執行緒安全是這麼的相近,但既然拿出來了,肯定是有區別的,下面就說說他們之間的區別和聯絡。要先解釋這兩個詞語才行。執行緒安全 似乎是在牛客網刷題的時候看到乙個正確的選項說的是,執行緒安全問題都是由全域性變數及靜態...
可重入和執行緒安全
綜觀整個文件,術語可重入和執行緒安全總是被用來標記類和函式,表明他們如何被用在多執行緒程式中。乙個執行緒安全的函式能被多個執行緒同時呼叫,甚至在這些呼叫使用共享資料時,因為所有對共享資料的引用是序列進行的。乙個可重入的函式也能被多個執行緒同時呼叫,但前提是每個呼叫只使用它們自己的資料。所以,乙個執行...
可重入和執行緒安全
1 定義 1 執行緒安全 多個執行緒同時執行一段 不會造成資源的衝突,不會產生錯誤的結果,那麼這段 是執行緒安全的。2 可重入 多個執行流反覆執行一段 其結果不會發生改變。2 條件 1 常見執行緒安全滿足的條件 2 常見可重入函式滿足的條件 3 區別 可重入的函式必定是執行緒安全的,而執行緒安全的函...