2017-05-26 39 views
1

我有三個類,我們稱它們爲A,B和HardwareDriver。每個類都有一個實例。 a和b運行在兩個不同的線程中。他們都通過HardwareDriver的一個實例訪問硬件。喜歡的東西:互斥體作爲使用pthreads的類成員

Class A { 
... }; 

Class B { 
... }; 

Class HardwareDriver { 
    public: 
     int accessHardware(); 
}; 

A a; 
B b; 
HardwareDriver hd; 
pthread_t aThread; 
pthread_t bThread; 

main() { 
    pthread_create(&aThread, NULL, &A::startA, &a); 
    pthread_create(&bThread, NULL, &B::startB, &b); 

    while (...) { }; 
    return 0; 
} 

硬件不能由A和B在同一時間訪問,所以我需要保護的代碼與互斥。我是多線程新手,但直觀地說,在通過調用方法hd.accessHardware()請求硬件訪問之前,我會在A和B的方法中鎖定互斥鎖。

現在我想知道是否有可能在hd.accessHardware()中執行鎖定以實現更多封裝。這仍然是線程安全的嗎?當你做任何閱讀操作

+0

a&b或線程是否使用HardwareDriver的相同對象?如果是,那麼確保只有一個HardwareDriver對象被創建。如果你在兩個線程中都使用單個對象,這將是安全的 – Pravin

+0

如果我確定沒有其他類需要同步對共享資源的訪問,並且如果調用accessHardware,我只會在A/B中執行鎖定/解鎖嚴重地在非多線程的情況下,在這種情況下,互斥可能會增加一些開銷。聽起來難以置信:) –

回答

0

它通過調用方法hd.accessHardware()請求硬件訪問之前,我會鎖定的AB方法互斥。

這會造成在致電hd.accessHardware()之前忘記鎖定該互斥鎖的風險。

現在我想知道如果可能的話,進行在hd.accessHardware()鎖定更多的封裝。這仍然是線程安全的嗎?

,消除忘記鎖是互斥的風險,讓您的API更難誤操作。這仍然是線程安全的。

0

當C/C做多線程編程++,你應該確保在任何您的線程爲寫作訪問的數據被鎖定,您可以lockfree離開READONLY數據。

鎖定操作必須具有更小的範圍不可能性,如果兩個對象訪問一個單一的資源,你需要一個信號量/互斥體,使用兩個會暴露你的危險deadlocks

所以,在你的例子中,你應該在HardwareDriver類中添加一個互斥鎖,並在每次讀/寫任何類數據時鎖定/解鎖它。

你並不需要鎖定本地數據(堆棧分配的局部變量),你並不需要鎖定在reentrant方法。

既然你正在編寫C++,我們在2017年,我想你可以用了,建議你直接使用的std ::線程的std ::互斥而不是並行線程的。在Linux中,C++本地線程支持是對pthread的一個小包裝,因此在嵌入式目標中使用它們的開銷也可以忽略不計。

1

是的,你可以在你的HardwareDriver類中有一個互斥量,並且在你的類方法中有一個臨界區。它仍然是安全的。請記住,如果您複製對象,您也將擁有互斥量。

+0

HardwareDriver應該有一個私人拷貝構造函數/賦值操作符以防止任何意外複製 - 並且互斥量必須(顯然)不是在本地聲明的,而是作爲HardwareDriver的成員 – nos