目录
- 1 背景
- 2 方法
1 背景
力扣1116题 打印零和奇偶数。
2 方法
方法1:原子操作
class ZeroEvenOdd {
private:int n;atomic<int> flag = 0;
public:ZeroEvenOdd(int n) {this->n = n;}// printNumber(x) outputs "x", where x is an integer.void zero(function<void(int)> printNumber) {for (int i = 1; i <= n; ++i) {while (flag != 0) {this_thread::yield();}printNumber(0);if (i % 2 == 0) {flag = 2;} else {flag = 1;}}}void even(function<void(int)> printNumber) {for (int i = 2; i <= n; i += 2) {while (flag != 2) {this_thread::yield();}printNumber(i);flag = 0;} }void odd(function<void(int)> printNumber) {for (int i = 1; i <= n; i += 2) {while (flag != 1) {this_thread::yield();}printNumber(i);flag = 0;}}
};
方法2:互斥锁和变量控制
class ZeroEvenOdd {
private:int n;mutex m;condition_variable cv;int flag = 0;
public:ZeroEvenOdd(int n) {this->n = n;}// printNumber(x) outputs "x", where x is an integer.void zero(function<void(int)> printNumber) {for (int i = 1; i <= n; ++i) {unique_lock<mutex> lock(m);cv.wait(lock, [&] {return flag == 0;});printNumber(0);if (i % 2 == 0) {flag = 2;} else {flag = 1;}cv.notify_one();}}void even(function<void(int)> printNumber) {for (int i = 2; i <= n; i += 2) {unique_lock<mutex> lock(m);cv.wait(lock, [&] {return flag == 2;});printNumber(i);flag = 0;cv.notify_one();}}void odd(function<void(int)> printNumber) {for (int i = 1; i <= n; i += 2) {unique_lock<mutex> lock(m);cv.wait(lock, [&] {return flag == 1;});printNumber(i);flag = 0;cv.notify_one();}}
};
方法3:信号量
#include <semaphore.h>class ZeroEvenOdd {
private:int n;sem_t printOdd, printEven, numDone;
public:ZeroEvenOdd(int n) {this->n = n;sem_init(&printOdd, 0, 0);sem_init(&printEven, 0, 0);sem_init(&numDone, 0, 1);}// printNumber(x) outputs "x", where x is an integer.void zero(function<void(int)> printNumber) {for (int i = 1; i <= n; ++i) {sem_wait(&numDone);printNumber(0);if (i % 2 == 0) {sem_post(&printEven);} else {sem_post(&printOdd);}}}void even(function<void(int)> printNumber) {for (int i = 2; i <= n; i += 2) {sem_wait(&printEven);printNumber(i);sem_post(&numDone);} }void odd(function<void(int)> printNumber) {for (int i = 1; i <=n; i += 2) {sem_wait(&printOdd);printNumber(i);sem_post(&numDone);}}
};