2013-07-30 30 views
0

我正在閱讀關於鎖定和設計應用C++的書籍。單線程在多線程中的使用

void addRef() { ref++; } 
void subRef() { if(--ref == 0) delete this; } 

儘管像裁判聲明++看起來瑣碎,也不能保證 ,它是原子。但是在你去寫這個代碼並添加 鎖之前,你需要知道你的應用程序將如何使用它。在這個 特定示例中,如果addRef在subRef之後被調用,則會創建一個錯誤。 問題不在於缺少鎖,而是糟糕的設計。如果對象 必須持續超出線程範圍,則應該通過不會超出範圍的其他線程創建並擁有 。

我上面的文字問題是

  1. 是什麼筆者糟糕的設計意味着以及如何這是由「如果一個對象必須持續超過一個線程的範圍內避免,應創建並擁有一個不會超出範圍的不同線程。「 ?請求舉一個例子。
+1

'std :: atomic'也可以。但是'刪除這個'無論如何都是可怕的 - 對象內的參考計數器有什麼好處? – nijansen

+1

爲什麼你在問題標題中提到單身人士,而在你的實際問題中沒有任何關係? –

回答

1
void thread1work(RefCntObj* refcntObj) 
{ 
    refcntObj.addRef(); 
    // any work 
    refcntObj.subRef(); 
} 

int main(void) { 
    RefCntObj* refcntObj= new RefCntObj(); // I assume the constructor calls addRef() 
    std::thread t(thread1work, std::ref(f)); 
    refcntObj->subRef(); // may be called after thread1Work or before it 
} 

不保證該thread1work將之前主要的refcntObj->subRef();被調用。在這種情況下,對象已經被刪除,指針無效。

0

由於代碼設計不佳,作者意味着類和方法的構造很差;在哪裏放置什麼以及該位置如何讓您的代碼可訪問。

「如果一個對象必須持續超出一個線程的範圍,它應該被創建並由一個不會超出範圍的不同線程擁有。

簡而言之,上面的意思是說,如果你在B中有B(線程),但是你還需要在C中使用B,那麼你必須從線程(A)中刪除B並且使它獨立於它,這樣你就可以在既有使用和C.

0

誰知道?你必須問作者。這看起來像經典引用計數對我來說:爲了安全起見,你將有 要麼使用一個互斥鎖,以保護所有訪問ref,或使 ref某種形式的原子變量。 (C++ 11對std::atomic<int>的整個範圍的 功能,您可以使用。)

至於引用的文字:你可以做什麼不安全的,如果 你不使用它的權利。如果兩個線程正在訪問同一個 實例,則ref應該至少爲2,因此如果 一個線程刪除該引用,該對象仍將繼續存在 。不需要任何額外的線程 複雜的事情。