notify std :: condition_variable在std :: Future上等待std :: async从异步函数内部返回

发布于 2025-01-21 09:41:02 字数 1081 浏览 2 评论 0原文

给定以下代码,我的问题是std :: condition_variable是否可以保证在lambda返回后在州的std :: future查看,即std :: fune_status :: ready。或者,如果可能发生std :: procention_variable在使用lambda的返回值以更新std :: future future之前被唤醒。在这种情况下,工人可能会永远卡住,因为它不会再次通知。

我猜想的另一个公式是,在使用lambda的返回值以更新std :: future future的状态之前,保证innion_lock是否可以保证不会发布。

实际上,到目前为止,这似乎很好。问题更多是确保这是安全的还是该代码中的种族条件。

std::mutex m;
std::future<bool> task;
std::condition_variable cv;

void dispatcher() {
    std::lock_guard lock(m);

    task = std::async(std::launch::async, [&] {
        // Do work...

        std::lock_guard inner_lock(m);
        cv.notify_one();
        return true;
    });
}

void worker() {
    auto task_ready = [&] {
        return task.valid() && task.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
    };

    std::unique_lock<std::mutex> lock(m);

    cv.wait(lock, task_ready);

    bool result = task.get();
    
    // Do some more work...
}

Given the following code my question is whether precondition of the std::condition_variable is guaranteed to see the std::future in the state after the lambda returned, i.e. std::future_status::ready. Or if it could happen that the std::condition_variable is woken up before the return value of the lambda is used to update the state of the std::future. In which case the worker might be stuck forever as it will not be notified again.

I guess another formulation would be whether the inner_lock is guaranteed to not be released before the return value of the lambda is used to update the state of the std::future.

In practice this seems to work fine so far. The question is more whether this guaranteed to be safe or whether there is a race condition in this code.

std::mutex m;
std::future<bool> task;
std::condition_variable cv;

void dispatcher() {
    std::lock_guard lock(m);

    task = std::async(std::launch::async, [&] {
        // Do work...

        std::lock_guard inner_lock(m);
        cv.notify_one();
        return true;
    });
}

void worker() {
    auto task_ready = [&] {
        return task.valid() && task.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
    };

    std::unique_lock<std::mutex> lock(m);

    cv.wait(lock, task_ready);

    bool result = task.get();
    
    // Do some more work...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文