看板 C_and_CPP 關於我們 聯絡資訊
最近遇到一個問題, 我們的程式庫設計成有自己的worker thread 負責回覆客戶端一些資訊(用意是讓main thread專心處理UI) 下面的code是一個簡化的例子 template<typename Handler> class Worker : public WorkerBase { mutex mtx_; condition_variable cond_; thread thrd_; Handler handler_; public: Worker(Handler handler) : handler_(handler) { mutex::scoped_lock lock(mtx_); thread(ref(*this)).swap(thrd_); } ~Worker(void) { thread thrd; mutex::scoped_lock lock(mtx_); // wait callback return thrd.swap(thrd_); cond_.notify_one(); lock.unlock(); thrd.join(); } void operator()(void) { mutex::scoped_lock lock(mtx_); while (thrd_.joinable()) { handler_(); // SB calls Worker::~Worker() cond_.wait(lock); } } }; 顯而易見如果在handler_()裡再呼叫~Worker()就會deadlock 原本上面提示我用reference count,實作後發現會違反另一個需求: 由main thread呼叫~Worker()與callback是同步的(如範例所示) 之後我看了asio的精妙作法,想提出來問這樣改是否ok 首先加入dispose(),之後不直接呼叫~Worker() void Worker::dispose(void) { if (asio::detail::call_stack<Worker>::contains(this)) { thread(bind(&checked_delete, this)).detach(); } else checked_delete(this); } 並在operator()中加入: asio::detail::call_stack<Worker>::context ctx(this); 簡單的說就是拿asio::detail::call_stack來判斷是否在callback中 試著結束worker thread,是則用另一個thread來完成這件事 否則(是在main thread中)就照原設計join worker thread 想請問板上的先進們這樣做會不會有潛在的危機? 亦或是有更好的作法嗎? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.204.92.148