【1115. 交替列印FooBar】

原程式如下,我們需要基于原程式進行修改:
class FooBar {
private:
int n;
public:
FooBar(int n) {
this->n = n;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
// printFoo() outputs "foo". Do not change or remove this line.
printFoo();
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
// printBar() outputs "bar". Do not change or remove this line.
printBar();
}
}
};
方法一:使用信号量
#include <semaphore.h>
class FooBar {
private:
int n;
sem_t cfoo;
sem_t cbar;
public:
FooBar(int n) {
this->n = n;
sem_init(&cfoo, 0, 0);
sem_init(&cbar, 0, 1);
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
sem_wait(&cbar);
printFoo();
sem_post(&cfoo);
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
sem_wait(&cfoo);
printBar();
sem_post(&cbar);
}
}
};
方法二:使用互斥鎖
class FooBar {
private:
int n;
mutex cfoo;
mutex cbar;
public:
FooBar(int n) {
this->n = n;
cbar.lock();
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
cfoo.lock();
printFoo();
cbar.unlock();
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
cbar.lock();
printBar();
cfoo.unlock();
}
}
};
方法三:使用原子變量
class FooBar {
private:
int n;
atomic<bool> flag = true;
public:
FooBar(int n) {
this->n = n;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
while (!flag) this_thread::yield(); // 釋放時間片
printFoo();
flag = false;
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
while(flag) this_thread::yield();
printBar();
flag = true;
}
}
};
類似的LeetCode題目還有【1114. 按序列印】和【1116. 列印零與奇偶數】
【1114. 按序列印】
信号量解法:
#include <semaphore.h>
class Foo {
public:
Foo() {
sem_init(&firstJobDone, 0, 0);
sem_init(&secondJobDone, 0, 0);
}
void first(function<void()> printFirst) {
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
sem_post(&firstJobDone);
}
void second(function<void()> printSecond) {
sem_wait(&firstJobDone);
// printSecond() outputs "second". Do not change or remove this line.
printSecond();
sem_post(&secondJobDone);
}
void third(function<void()> printThird) {
sem_wait(&secondJobDone);
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
protected:
sem_t firstJobDone;
sem_t secondJobDone;
};