【Leetcode】1116. Print Zero Even Odd

题目地址:

https://leetcode.com/problems/print-zero-even-odd/description/

给定下面的类:

class ZeroEvenOdd {
 private:
	int n;

 public:
  ZeroEvenOdd(int n) {
	this->n = n;
  }

  // printNumber(x) outputs "x", where x is an integer.
  void zero(function<void(int)> printNumber) {}
  void even(function<void(int)> printNumber) {}
  void odd(function<void(int)> printNumber) {}
};

同一个这个类的实例会传给三个线程,三个线程分别调用三个函数,要求打印出 010203...0 n 010203...0n 010203...0n这样的字符串。三个函数只能打印符合条件的数字。

要开一个锁让三个线程只能有一个运行,用一个bool变量表示是否应该打印 0 0 0,用另一个int变量表示当前应该打印什么数,一开始让打印 0 0 0的线程运行,然后让它唤醒所有线程,其余线程通过一个condition_variable的判断来决定其是否应该被唤醒。代码如下:

class ZeroEvenOdd {
 private:
  int n;
  int turn, cnt;
  mutex mu;
  condition_variable cv;

 public:
  ZeroEvenOdd(int n) {
    this->n = n;
    turn = 0;
    cnt = 1;
  }

  // printNumber(x) outputs "x", where x is an integer.
  void zero(function<void(int)> printNumber) {
    while (cnt <= n) {
      unique_lock<mutex> ul(mu);
      cv.wait(ul, [this] { return turn == 0 || cnt > n; });
      if (cnt > n) break;
      printNumber(0);
      turn = cnt % 2 == 0 ? 2 : 1;
      cv.notify_all();
    }
  }

  void even(function<void(int)> printNumber) {
    while (cnt <= n) {
      unique_lock<mutex> ul(mu);
      cv.wait(ul, [this] { return turn == 2 || cnt > n; });
      if (cnt > n) break;
      printNumber(cnt++);
      turn = 0;
      cv.notify_all();
    }
  }

  void odd(function<void(int)> printNumber) {
    while (cnt <= n) {
      unique_lock<mutex> ul(mu);
      cv.wait(ul, [this] { return turn == 1 || cnt > n; });
      if (cnt > n) break;
      printNumber(cnt++);
      turn = 0;
      cv.notify_all();
    }
  }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值