首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11修订的` `std::latch`‘实现

C++11修订的` `std::latch`‘实现
EN

Code Review用户
提问于 2021-10-24 18:59:01
回答 1查看 290关注 0票数 3

这个问题是在这个问题上提出的。

while-loop转换为使用std::condition_variable的条件等待之后,我想知道这段在C++11中实现std::latch来自C++20的的代码是否还存在任何缺陷/问题:

代码语言:javascript
复制
#include <condition_variable>
#include <cstdint>
#include <atomic>
#include <mutex>

class latch {
    std::atomic<std::ptrdiff_t> counter_;
    mutable std::condition_variable cv_;
    mutable std::mutex mut_;

public:
    explicit latch(std::ptrdiff_t const def = 1) : counter_(def) {}

    void count_down(std::ptrdiff_t const n = 1) {
        counter_ -= n;
        cv_.notify_all();
    }

    void wait() const {
        if (counter_.load(std::memory_order_relaxed) == 0) return;
        std::unique_lock<std::mutex> lock(mut_);
        cv_.wait(lock, [=] { return counter_.load(std::memory_order_relaxed) == 0; });
    }

    bool try_wait() const noexcept {
        return counter_.load(std::memory_order_relaxed) == 0;
    }

    void arrive_and_wait(std::ptrdiff_t const n = 1) {
        count_down(n);
        wait();
    }

    static constexpr std::ptrdiff_t max() noexcept {
        return std::numeric_limits<std::ptrdiff_t>::max();
    }
};
EN

回答 1

Code Review用户

发布于 2021-10-25 10:28:28

对于构造函数,有一些次要的挑剔:

  • 应该是constexpr
  • 它不应该有默认的参数。
  • 我们应该检查这个参数是否有效(不是否定的,也不大于max())。标准称它是未定义的行为,因此我们在技术上不必这样做,但对assert来说,这比默默地继续进行要好。

另一件事:

代码语言:javascript
复制
    counter_ -= n;
    cv_.notify_all();

operator-=()在做counter.fetch_sub(n, std::memory_order_seq_cst);

虽然这个内存顺序是安全的,但我不确定它是否必要。我怀疑你可以摆脱std::memory_order_release (注意:我不太熟悉atomic<>s,所以你可能需要一个第二种意见)。

在任何情况下,使用显式fetch_sub调用更清楚,并且还允许我们添加一个断言,即以前的counter值大于或等于n

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/269344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档