2011-08-01 81 views
1

在我使用ATL的免費線程進程內COM對象中,我想添加一個僅在FinalConstruct()中設置的成員變量,並且只能在FinalRelease()中只讀。沒有其他代碼會操縱該成員變量。FinalConstruct()/ FinalRelease()中需要同步嗎?

我懷疑當訪問該成員變量時是否需要同步。我仔細閱讀ATL源代碼,看起來像那些方法總是被調用不超過一次,因此只能從一個線程中調用。

這是正確的假設嗎?我可以省略同步嗎?

回答

3

是的,這個假設是正確的。可以把它看作C++構造函數和析構函數的擴展。從理論上講,你可以從另一個線程調用一個COM對象的方法,而FinalRelease()正在執行。雖然這是未定義的行爲,而不是預期的發生。你不應該試圖保護自己,就像你不會試圖保護自己免受析構函數中的其他線程一樣。如果你必須在析構函數中保護自己,那麼設計通常會被破壞(這將表明你的線程之間沒有適當的終止協議)。

可以從另一個線程調用FinalRelease()的唯一方法是客戶端代碼沒有對象的有效引用計數,或者代碼的某些其他部分釋放兩次。這是一個嚴重錯誤,並且可能最終會在崩潰中崩潰,與您可能遇到的任何同步錯誤完全無關。用於管理對象引用計數的ATL代碼是線程安全的,不會打開任何爭用條件。

至於FinalConstruct(),在FinalConstruct()已成功返回代碼之前,該對象的引用不會返回給任何客戶端。