c++ - std::condition_variables 可以用作计数信号量吗?

标签 c++ multithreading c++11 semaphore condition-variable

这是 Can C++11 condition_variables be used to synchronize processes? 的后续行动.

std::condition_variable 对象可以用作计数信号量吗?

我认为不是因为对象似乎绑定(bind)到 std::mutex,这意味着它只能用作二进制信号量。我在网上看过,包括here , here , 和 here , 但找不到将这些对象用作计数信号量的引用或示例。

最佳答案

是的。

struct counting_sem {
  counting_sem(std::ptrdiff_t init=0):count(init) {}
  // remove in C++17:
  counting_sem(counting_sem&& src) {
    auto l = src.lock(); // maybe drop, as src is supposed to be dead
    count = src.count;
  }
  counting_sem& operator=(counting_sem&& src) = delete;
  void take( std::size_t N=1 ) {
    if (N==0) return;
    auto l = lock();
    cv.wait(l, [&]{
      if (count > 0 && count < (std::ptrdiff_t)N) {
        N -= count;
        count = 0;
      } else if (count >= (std::ptrdiff_t)N) {
        count -= N;
        N = 0;
      }
      return N == 0;
    });
  }
  void give( std::size_t N=1 ) {
    if (N==0) return;
    {
      auto l = lock();
      count += N;
    }
    cv.notify_all();
  }
  // reduce the count without waiting for it
  void reduce(std::size_t N=1) {
    if (N==0) return;
    auto l = lock();
    count -= N;
  }
private:
  std::mutex m;
  std::condition_variable cv;
  std::ptrdiff_t count;

  auto lock() {
    return std::unique_lock<std::mutex>(m);
  }
  auto unlocked() {
    return std::unique_lock<std::mutex>(m, std::defer_lock_t{});
  }
};

代码未经测试或编译,但设计合理。

take(7) 不等同于 for(repeat 7 times) take():相反,如果不是这样,它会尽可能多地进行阻塞够了。

修改它直到有足够的东西才需要任何东西很容易:

      if (count >= (std::ptrdiff_t)N) {
        count -= N;
        N = 0;
      }

关于c++ - std::condition_variables 可以用作计数信号量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40335671/

相关文章:

c++ - 单词的 SQL 哈希表

c# - 并行 ForEach 和 ConcurrentBag

android - 用于更新小部件的 AsyncTask - 如何访问 onPostExecute() 中的 TextView ?

c++ - 在其静态递归函数中展开struct类型模板参数包

c++ - 我应该像这样使用 constexpr 吗?

c++ - 一个偶尔的作家,多个 std::map 的常客

c++ - 将 argv 和 argc 传递给线程

c++ - 指针数组无法解释的行为(带有浅拷贝)c++

c++ - 下面描述的概念如何在 C++14 中设计?

java - 在现有线程的未捕获异常处理程序中启动一个新线程