当前位置: 首页 > 知识库问答 >
问题:

STD::Condition_Variables可以用作计数信号量吗?

申屠裕
2023-03-14

共有1个答案

西门经国
2023-03-14

是的。

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(重复7次)take():相反,如果不够,它会尽可能多地占用块。

      if (count >= (std::ptrdiff_t)N) {
        count -= N;
        N = 0;
      }
 类似资料:
  • 我有多个进程与Sempahore同步。我知道这段代码不允许gurantee出现这样的情况:在sem_getvalue期间,即使值变为零,甚至在调用特定进程中的sem_post之前,anotehr进程也可能调用sem_post,使值变为2。如何解决这种情况。 我的问题不能通过互斥体来解决,在我的问题中,有些进程只用于信号,即操作,而在互斥体中,所有进程都将等待并不断地发出信号

  • 与二值信号量可以类比成只能保存一个数据的队列一样,计数信号量可以类比成长度大于1的队列,用户在使用的时候同样不关注队列中的数据,只关心这个队列是不是非空的。 计数信号量的主要用在两个方面: 计数事件 事件每次发生时,都会增加计数信号量的值,而任务在每次处理完后都会将计数信号量的值减少。因此,计数值其实代表着已经发生的事件次数和已经处理完的事件次数只差,也因此,计数信号量的初始值设置成0是合理的。

  • 在GATE计算信号量时会问到这些问题。 一般来说,问题非常简单,只包含减法和加法。 以下类型的问题可以在GATE中询问。 计数信号量初始化为12。然后在这个信号量上计算10P(等待)和4V(信号)操作。 结果是什么? 因此,计数信号量的最终值是。

  • 有一些情况需要同时在临界区执行多个进程。 但是,当我们需要同时在临界区中有多个进程时,可以使用计数信号量。 信号量实现的编程代码如下所示,其中包括信号量的结构以及在临界区中可以执行的入口和退出的逻辑。 在这种机制中,临界区的入口和退出是根据计数信号量的值执行的。在任何时间点计算信号量的值表示可以同时在临界区输入的最大进程数。 想要进入临界区的进程首先将信号量值减1,然后检查它是否为负值。如果它变为

  • 问题内容: 信号量可以小于0吗?我的意思是说我有一个N = 3的信号量,并且我叫“ down” 4次,那么N将保持为0,但是一个进程将被阻塞吗? 同样,如果一开始我打电话给我,N是否可以高于3?因为如我所见,如果N可以大于3,如果一开始我调用了两次,那么以后我可以调用的次数比我可以调用的次数多,因此在关键部分放置了更多的进程,则信号量使我可以。 如果有人为我澄清一下,我将不胜感激。 格雷格 问题答