簡體   English   中英

boost::asio 需要異步鎖定機制

[英]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(...) {
    ...
}

雖然我認為這會起作用,但感覺就像

  1. 這是對計時器類的濫用,因為我什至沒有使用它們的“計時器”功能
  2. 使用某種異步等待鎖,這個任務會更自然地解決(將busy標志和通知組合成一個原語)

我在 asio 中搜索了異步鎖,但找不到。 然而,這個問題對我來說似乎如此根本,以至於我無法相信,沒有比我提到的更好的解決方案了。 請注意,我不想使用真正的鎖,也不需要建議來使我的代碼線程安全,因為 API 應該運行單線程。

問題

  1. asio中有異步鎖機制嗎?
  2. 如果沒有,有什么原因嗎?
  3. 有沒有使用股線優雅地解決這個問題的替代方法?

簡短的回答,不,沒有鎖定機制。 正確的方法是使用股線。

更長的答案:

在幾乎所有情況下,如果您需要一組連續發生的步驟,那么 ASIO 解決方案就是使用 strands。 在您的情況下,您的兩個客戶端向 strand 提交回調,可以查看整體 state,並采取正確的操作。

如果您希望您的客戶端是同步的(即等待操作完成),則傳遞給 strand 的回調應該使用某種同步原語,例如promise來表示完成。

因此,客戶端將創建一個promise ,通過get_future獲取未來,並將 promise 以及任何其他信息傳遞給鏈。 任何數量的客戶都可以合法地這樣做。

然后,strand 將以某種順序執行所有回調,確保一次只執行一個回調。 完成后, promise可以完成,然后進行下一個操作。 客戶可以等到他們的回調完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM