[Chromium]如何安全的使用PostTask

Horky發表於2016-01-09

PostTask引數決策樹



如何傳遞繫結的物件

官方的解釋總是最權威,有疑問看這裡或者直接看程式碼中的說明: bind_helpers.h. 

傳值方式描述
this 或 物件指標

如果物件本身是一個RefCountedThreadSafe, 沒有問題.

如果是個裸指標,應當儘量避免,除非你可以保證它的執行緒安全.

base::Unretained

注意:使用這個的前提是有其它同步機制保障物件的生命週期.

  1. 如果有其它同步機制保障物件的生命週期,可以使用Unretained()傳遞非引用計數的物件.
  2. 如果是一個非引用計數的物件,可以使用Unretained()封裝起來.
base::Owned

如果是臨時物件,或者擔心任務執行完成後物件可能出現洩露,可以使用Owned, 表示由Task

持有物件的所有權,在結束時析構它.

base::Passed如果要執行Task需要傳入scoped指標,就可以使用它轉換,它也可以避免拷貝,而是類似move語義.
base::ConstRef類似常量引用,不希望bind過程出現拷貝,就可以使用它.
base::IgnoreResult如果Task要呼叫的方法帶有返回值,而你又不關心返回值就可以使用IgnoreResult來傳入物件指標.

 

討論:為什麼要避免引用計數?

如果這樣一直將以引用計數來使用物件豈不最為簡單,為什麼要避免引用計數?

Chromium智慧指標指引中的解釋:

  • Reference-counted objects make it difficult to understand ownership and destruction order, especially when multiple threads are involved. There is almost always another way to design your object hierarchy to avoid refcounting. Avoiding refcounting in multithreaded situations is usually easier if you restrict each class to operating on just one thread, and use PostTask() and the like to proxy calls to the correct thread. base::Bind(), WeakPtr, and other tools make it possible to automatically cancel calls to such an object when it dies. Note that too much of our existing code uses refcounting, so just because you see existing code doing it does not mean it's the right solution. (Bonus points if you're able to clean up such cases.)

還可以參考: 謹慎使用智慧指標

參考

關於Callback和Bind對物件所有權更完整的解釋



相關文章