需求
在多线程环境下按序打印firstsecondthird,并且保证打印顺序不会出错
使用信号量
#include<semaphore.h>
class Foo {
sem_t sem1;
sem_t sem2;
public:
Foo(){ //sem_init 初始化信号量
//对信号量进行初始化;
sem_init(&sem1,0,0);sem_init(&sem2,0,0);
}
void first(function<void()> printFirst) {
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
sem_post(&sem1); //p操作,对信号量进行+1;
}
void second(function<void()> printSecond) {
sem_wait(&sem1); //对sem1进行v操作减一;
// printSecond() outputs "second". Do not change or remove this line.
printSecond();
sem_post(&sem2); //+1
}
void third(function<void()> printThird) {
sem_wait(&sem2); //减一;
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
};
条件变量+mutex+lock_Guard
class Foo {
bool firstT;
bool secondT;
mutex mtx;
condition_variable cv1,cv2;
public:
Foo() {
firstT=false,secondT=false ;
}
void first(function<void()> printFirst) {
lock_guard<mutex> lg(mtx); //对mtx初始化,作用域结束自动释放
printFirst();
firstT=true;
cv1.notify_one(); //条件变量随机唤醒一个线程;
}
void second(function<void()> printSecond) {
unique_lock<mutex> ul(mtx); //加锁
//只有表达式为false的时候会阻塞线程,为true的时候会唤醒线程;
cv1.wait(ul,[&]{ return this->firstT;}); //lambda表达式
printSecond();
secondT=true;
cv2.notify_one(); //唤醒一个线程;
}
void third(function<void()> printThird) {
unique_lock<mutex> ul(mtx);
cv2.wait(ul,[&]{ return this->secondT; });
printThird();
}
};
1115 交替打印FooBar
两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。
请设计修改程序,以确保 “foobar” 被输出 n 次。
条件变量 + unique_lock
class FooBar {
private:
int n;
mutex mtx;
condition_variable cv;
bool foo_down;
public:
FooBar(int n) {
this->n = n;
foo_down=false;
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
unique_lock<mutex> lock(mtx);
cv.wait(lock,[&](){return !foo_down;}); //这是个lambda表达式;
// printFoo() outputs "foo". Do not change or remove this line.
printFoo();
foo_down=true;
cv.notify_one();
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
unique_lock<mutex> lock(mtx);
cv.wait(lock,[&](){return foo_down;});
// printBar() outputs "bar". Do not change or remove this line.
printBar();
foo_down=false;
cv.notify_one();
}
}
};
使用sem信号量
#include<semaphore.h>
class FooBar {
private:
int n;
sem_t sem1;
sem_t sem2;
public:
FooBar(int n) {
this->n = n;
sem_init(&sem1,0,0);
sem_init(&sem2,0,1); //最后一个值是设置value
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
// printFoo() outputs "foo". Do not change or remove this line.
sem_wait(&sem2);
printFoo();
sem_post(&sem1);
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
sem_wait(&sem1);
// printBar() outputs "bar". Do not change or remove this line.
printBar();
sem_post(&sem2);
}
}
};
linux下生产者消费者模型
#include<pthread.h>
class FooBar {
private:
int n;
pthread_mutex_t mutex;
pthread_cond_t hasfoo,hasbar;
bool foos;
public:
FooBar(int n) {
this->n = n;
foos=false;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&hasfoo,NULL);
pthread_cond_init(&hasbar,NULL);
}
void foo(function<void()> printFoo) {
for (int i = 0; i < n; i++) {
pthread_mutex_lock(&mutex);
while(foos)
{
pthread_cond_wait(&hasbar,&mutex);
}
// printFoo() outputs "foo". Do not change or remove this line.
printFoo();
foos=true;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&hasfoo);
}
}
void bar(function<void()> printBar) {
for (int i = 0; i < n; i++) {
pthread_mutex_lock(&mutex);
while(!foos)
{
pthread_cond_wait(&hasfoo,&mutex);
}
// printBar() outputs "bar". Do not change or remove this line.
printBar();
foos=false;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&hasbar);
}
}
};