4

我正在使用GCD爲類添加線程安全性。使用GCD和代碼重用:避免可重入代碼死鎖

我班的一些公共方法被其他公共方法調用。但是,這會導致重入鎖定問題:如果我使用同步GCD塊(在某些情況下)保護適當的公開可見方法,則重用意味着有時我會嘗試在當前隊列上運行另一個同步塊,這會導致死鎖。

什麼是最優雅的解決方案?一個顯而易見的方法是使用適當方法的內部版本,沒有任何GCD塊,以及具有GCD塊的外部公開版本的方法將調用包裝到interal方法中。這不太適合我。

+2

只要你的類不需要對隊列中運行的外部代碼進行任何回調,你的「顯而易見的方法」就非常好。在這種情況下,外部代碼可能會調用另一個公共方法並導致死鎖。 – 2013-03-15 22:45:30

+2

還有另一個更微妙的問題,就是它可以防止子類覆蓋事物(因爲它們的覆蓋不會被調用,因爲它們不是內部版本)。如果這不是問題,這是做到這一點的最佳方式。如果這是一個問題,你需要(呃)遞歸鎖定,並且不能使用GCD。 – 2013-03-16 01:11:02

回答

0

這裏有幾個想法:

  1. 看看你能不能用一成不變的對象。這意味着無論何時一個方法會修改對象,它實際上會返回一個新的對象,並具有修改後的狀態。塊將繼續並使用這個新的對象。這很簡單,不需要特別照顧,但並非總是可行。

  2. 看看你的公共方法不能使用私有方法,攜帶狀態。由於每個塊都會帶有自己的內部狀態,所以你也是線程安全的。

如果你有一些實例的使用情況下,它可能會導致更多的想法...

0

我已經在我們的C++使用調度隊列同步類使用這樣的模式非常成功:

class Foo 
{ 
public: 
    void doSomething() { 
     dispatch_sync(fQueue, ^{ doSomething_sync(); }); 
    } 

private: 
    void doSomething_sync() { ... } 

private: 
    dispatch_queue_t fQueue; 
}; 

這裏的一般慣例是,在一類任一給定_sync方法,你只能調用其他方法_sync而不是他們的非公開_sync對口。