我有一個從boost::io_service
接收回調,並且由於一些原因我不能發佈通過共享指針回調(是的,我知道這是到正式方法的對象處理它),所以我用一個原始指針綁定處理程序。假設在這種情況下它是一個固定的要求。的阻塞取消Boost.Asio的
現在,如果我刪除的對象,它將,當然,仍然收到一個回調在一個優秀的套接字操作與「操作中止」錯誤代碼。
的問題:有沒有辦法強制所有操作的同步完成時,我與它擁有短耳對象(插座,定時器)一起刪除的對象?
我有一個從boost::io_service
接收回調,並且由於一些原因我不能發佈通過共享指針回調(是的,我知道這是到正式方法的對象處理它),所以我用一個原始指針綁定處理程序。假設在這種情況下它是一個固定的要求。的阻塞取消Boost.Asio的
現在,如果我刪除的對象,它將,當然,仍然收到一個回調在一個優秀的套接字操作與「操作中止」錯誤代碼。
的問題:有沒有辦法強制所有操作的同步完成時,我與它擁有短耳對象(插座,定時器)一起刪除的對象?
你不能;那時信息已經丟失了。你甚至無法比較函數對象是否相等,更不用說偷看內部並比較一些指針,然後決定做什麼。
所以,問題是:爲什麼你不能使用共享指針?
做到這一點的方法是使用共享指針和弱指針。如果你不想使用共享指針和弱指針,你可以自己實現底層機制。但是使用庫實現通常更可靠。
因此,在回調中使用弱指針,讓回調以weak_ptr作爲參數,調用wp.lock(),檢查它,如果它仍然有效,則對其進行解引用。在清除主shared_ptr和調用wp.lock()的另一個線程(假設您有多個線程)的情況下,仍然會出現爭用情況,但您可以通過在對象中使用標記來解決此問題。
更新與響應發表評論:
短耳並沒有強迫你使用一個shared_ptr/weak_ptr的組合。您可以自由構建自己的解決方案,但必須解決相同的問題。
假設你不能使用weak_ptr,你應該刪除對象,一旦你確定沒有別的東西會使用指針。原則上你有兩種基本的方法:
通過使用一些額外的數據結構來檢測該對象已被刪除。這是shared_ptr/weak_ptr在內部執行的操作,您可以自由構建自己的等效項。
等待一切完成,然後刪除該對象。不需要使用shared_ptr/weak_ptr,但您需要以某種方式執行本書。
在這些情況下,您最終會通過手動或使用庫來跟蹤哪些優秀。基本的任務是一樣的,但你並不是被迫使用一個庫。你被迫解決這個普遍問題。
你所要求的,同步「取消」每個優秀的操作,讓您可以安全地刪除對象的方式,減少對這些案件之一。
考慮:
class Obj {
void queue() { wait_for_io(this, bind(&Obj::io_done, this, _1)); }
void io_done(error_code const& error)
{
// Do stuff.
}
};
void kill_object(Obj* o)
{
cancel_outstanding_operations_for_obj(o);
delete o;
}
什麼調用cancel_outstanding_operations()做,如果調用的OBJ :: io_done()過程中的另一個線程?它是否等待它返回,還是因爲I/O操作完成而立即返回?在「立即返回」的情況下,「delete o」語句並不安全。在「等待它返回」的情況下,除了已經添加了一堆實現複雜性並且必須同步執行等待外,您還有上面的「等待所有事情完成」的情況。
是的我明白我可以使用weak_ptr,但假設我不能。似乎很愚蠢的是,沒有安全的方法來取消未使用shared_ptr的掛起操作。事實上,似乎Asio *強制我使用共享/弱指針進行異步回調,而不會留下任何擺動空間。更糟的是,這迫使我對一個對象有一種「limbo」狀態,當它從應用程序邏輯的角度來看不再有效時,但仍然可以接收到一個Asio回調。 –