Qt之可重入與執行緒安全

2021-09-23 14:38:08 字數 1517 閱讀 6039

本篇文章中,術語「可重入性」和「執行緒安全」被用來標記類與函式,以表明它們如何被應用在多執行緒應用程式中。

因此,乙個執行緒安全的函式總是可重入的,但乙個可重入的函式並不一定是執行緒安全的。

擴充套件開來,乙個可重入的類,指的是它的成員函式可以被多個執行緒安全地呼叫,只要每個執行緒使用這個類的不同的物件。而乙個執行緒安全的類,指的是它的成員函式能夠被多執行緒安全地呼叫,即使所有的執行緒都使用該類的同乙個例項也沒有關係。

注意:qt的一些類被設計為執行緒安全的,如果它們的目的是多執行緒。如果乙個函式沒有被標記為執行緒安全的或可重入的,它就不應該被不同的執行緒使用。如果乙個類沒有被標記為執行緒安全的或可重入的,該類的例項就不應該被多個執行緒訪問。

c++的類往往是可重入的,這只是因為它們只能訪問自己的資料。任何執行緒都能訪問乙個可重入類例項的乙個成員函式,只要同一時間沒有其它執行緒呼叫該例項的成員函式。例如,下面的counter類就是可重入的:

class counter

void increment()

void decrement()

intvalue() const

private:

int n;

};

該類不是執行緒安全的,因為如果多個執行緒試圖修改資料成員n,則結果是不確定的。這是因為++和–操作都不總是原子性的。事實上,它們一般被展開為3條機器指令:

將變數值裝入暫存器

增加或減少暫存器中的值

將暫存器中的值寫回記憶體

如果執行緒a和執行緒b同時將變數的舊值裝入暫存器,增加暫存器中的值,再寫回記憶體,它們最終會互相覆蓋,導致變數值僅增加了一次!

顯然,訪問應該是序列的: 執行緒a必須在無中斷的情況下執行完1.2.3.三個步驟(原子性),然後執行緒b才能開始執行,反之亦然。乙個使類是執行緒安全的簡單方法就是用乙個qmutex來保護資料成員的所有訪問。

class counter

void increment()

void decrement()

intvalue() const

private:

mutable qmutex mutex;

int n;

};

qmutexlocker類在其建構函式中自動鎖定mutex,並且當析構函式被呼叫時解鎖。鎖定mutex保證了其它執行緒的訪問都將是序列化的。mutex資料成員被宣告為mutable的,這是因為value()是乙個const函式,我們需要在其中lock和unlock該mutex。

許多qt的類都是可重入的,但不是執行緒安全的,因為執行緒安全意味著為鎖定與解鎖乙個qmutex增加額外的開銷。例如:qstring是可重入的,但不是執行緒安全的。你能夠同時從多個執行緒訪問不同的qstring的例項,但不能同時從多個執行緒訪問qstring的同乙個例項(除非用qmutex保護訪問)。

注意:多執行緒領域中的術語並不是完全標準化的。posix使用的可重入和執行緒安全的定義有些不用於它的c api。當qt和其它物件導向的c++類庫一起使用時,確保定義的理解。

Qt之可重入與執行緒安全

本篇文章中,術語 可重入性 和 執行緒安全 被用來標記類與函式,以表明它們如何被應用在多執行緒應用程式中。因此,乙個執行緒安全的函式總是可重入的,但乙個可重入的函式並不一定是執行緒安全的。擴充套件開來,乙個可重入的類,指的是它的成員函式可以被多個執行緒安全地呼叫,只要每個執行緒使用這個類的不同的物件...

Qt 可重入和執行緒安全

在整個文件中,術語 可重入 和 執行緒安全 用於標記類和函式,以指示它們如何在多執行緒應用程式中使用 因此,執行緒安全函式始終是可重入的,但可重入函式並非始終是執行緒安全的。通過擴充套件,如果可以從多個執行緒安全地呼叫其成員函式,則該類稱為可重入的,只要每個執行緒使用該類的不同例項即可。如果可以從多...

Qt 多執行緒之可重入與執行緒安全

qt 多執行緒之可重入與執行緒安全是本節要介紹的內容。在qt文件中,術語 可重入 與 執行緒安全 被用來說明乙個函式如何用於多執行緒程式。假如乙個類的任何函式在此類的多個不同的例項上,可以被多個執行緒同時呼叫,那麼這個類被稱為是 可重入 的。假如不同的執行緒作用在同乙個例項上仍可以正常工作,那麼稱之...