[英]boost::asio need for asynchronous locking mechanism
我需要開發一個 api,它同步允許訪問共享的異步資源。 為簡單起見,我們假設一個 boolean 資源resource
,這可能需要一些時間來切換其 state。 它當前設置為false
,兩個客戶端希望同時將其設置為true
。 我希望第二個客戶端看到一個操作正在進行中,並異步等待它的完成。 是否有可能以某種方式將完成處理程序添加到正在運行的異步操作中?
我目前正在嘗試做的是創建一個 asio 的計時器,將其過期時間設置為一個非常大的值,並在操作完成時取消它。 任何客戶端都會通過計時器取消獲得通知。
void set_true() {
mytimer.expires_after(<a long time>);
if ( !resource.busy )
resource.busy = true;
resource.async_set_true( [](){
resource.busy = false
mytimer.cancel();
});
mytimer.async_wait(do_return);
}
void do_return(...) {
...
}
雖然我認為這會起作用,但感覺就像
busy
標志和通知組合成一個原語)我在 asio 中搜索了異步鎖,但找不到。 然而,這個問題對我來說似乎如此根本,以至於我無法相信,沒有比我提到的更好的解決方案了。 請注意,我不想使用真正的鎖,也不需要建議來使我的代碼線程安全,因為 API 應該運行單線程。
問題
簡短的回答,不,沒有鎖定機制。 正確的方法是使用股線。
更長的答案:
在幾乎所有情況下,如果您需要一組連續發生的步驟,那么 ASIO 解決方案就是使用 strands。 在您的情況下,您的兩個客戶端向 strand 提交回調,可以查看整體 state,並采取正確的操作。
如果您希望您的客戶端是同步的(即等待操作完成),則傳遞給 strand 的回調應該使用某種同步原語,例如promise
來表示完成。
因此,客戶端將創建一個promise
,通過get_future
獲取未來,並將 promise 以及任何其他信息傳遞給鏈。 任何數量的客戶都可以合法地這樣做。
然后,strand 將以某種順序執行所有回調,確保一次只執行一個回調。 完成后, promise
可以完成,然后進行下一個操作。 客戶可以等到他們的回調完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.