题目:https://leetcode-cn.com/problems/print-foobar-alternately/
方法1:模仿信号量机制,使用两个整数来控制先后执行顺序。
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.
//相当于信号量的wait操作:
while (s2 < 1) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
s2--;
printFoo();
//相当于信号量的inc操作:
s1++;
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
// printBar() outputs "bar". Do not change or remove this line.
while (s1 < 1) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));//注释掉会超时错误
}
s1--;
printBar();
s2++;
}
}
private:
std::atomic<int> s1=0; //场景较为简单,不使用原子类型也可以
std::atomic<int> s2=1;
int s1 = 0;
int s2 = 1;
};
方法2:借助c++ std::mutex锁,本质上与方法1一样,时间消耗略增多,空间消耗也略增多。
class FooBar {
private:
int n;
public:
FooBar(int n) {
this->n = n;
m1.lock();
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
// printFoo() outputs "foo". Do not change or remove this line.
m2.lock();
printFoo();
m1.unlock();
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
// printBar() outputs "bar". Do not change or remove this line.
m1.lock();
printBar();
m2.unlock();
}
}
private:
std::mutex m1;
std::mutex m2;
};
方法3:借助条件变量, 时间和空间效率,完胜前两种方法:
C++条件变量--std::condition_variable的使用方法:https://blog.csdn.net/qq_35865125/article/details/108859681
class FooBar {
private:
int n;
public:
FooBar(int n) {
this->n = n;
m_foo_printed = false;
m_bar_printed = true;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
unique_lock<mutex> lck(m_mtx);
while(!m_bar_printed)
{
m_cv.wait(lck); //等bar打印完
}
// printFoo() outputs "foo". Do not change or remove this line.
printFoo();
m_foo_printed = true;
m_bar_printed = false;
m_cv.notify_one();
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
unique_lock<mutex> lck(m_mtx);
while(!m_foo_printed)
{
m_cv.wait(lck); //等foo打印完
}
// printBar() outputs "bar". Do not change or remove this line.
printBar();
m_bar_printed = true;
m_foo_printed = false;
m_cv.notify_one();
}
}
private:
mutex m_mtx;
condition_variable m_cv;
bool m_foo_printed; //foo打印完了
bool m_bar_printed; //bar打印完了
};