力扣1195. 交替打印字符串(信号量)
https://leetcode-cn.com/problems/fizz-buzz-multithreaded/
信号量
四个线程四个信号量
这题倒是不难,本质上是进程同步问题,使用信号量就好了。
在这道题上纠结了好久,一直超时,最后发现是因为线程没有主动结束。。
#include <semaphore.h>
class FizzBuzz {
private:
int n;
int cur;
sem_t fizzbuzzjob;
sem_t fizzjob;
sem_t buzzjob;
sem_t numberjob;
public:
FizzBuzz(int n) {
this->n = n;
cur=0;
sem_init(&fizzbuzzjob,0,0);
sem_init(&fizzjob,0,0);
sem_init(&buzzjob,0,0);
sem_init(&numberjob,0,1);
}
// printFizz() outputs "fizz".
void fizz(function<void()> printFizz) {
while(cur<=n)//控制线程退出
{
sem_wait(&fizzjob);
if(cur>n)break;
printFizz();
sem_post(&numberjob);
}
}
// printBuzz() outputs "buzz".
void buzz(function<void()> printBuzz) {
while(cur<=n)//控制线程退出
{
sem_wait(&buzzjob);
if(cur>n)break;
printBuzz();
sem_post(&numberjob);
}
}
// printFizzBuzz() outputs "fizzbuzz".
void fizzbuzz(function<void()> printFizzBuzz) {
while(cur<=n)//控制线程退出
{
sem_wait(&fizzbuzzjob);
if(cur>n)break;
printFizzBuzz();
sem_post(&numberjob);
}
}
// printNumber(x) outputs "x", where x is an integer.
void number(function<void(int)> printNumber) {
while(++cur<=n)
{
sem_wait(&numberjob);
if((cur%3)==0 && (cur%5)==0)
{
sem_post(&fizzbuzzjob);
}
else if((cur%3)==0)
{
sem_post(&fizzjob);
}
else if((cur%5)==0)
{
sem_post(&buzzjob);
}
else
{
printNumber(cur);
sem_post(&numberjob);
}
}
//让线程不阻塞,退出
sem_post(&fizzjob);
sem_post(&buzzjob);
sem_post(&fizzbuzzjob);
}
};
int main(int argc, char** argv){
FizzBuzz fizzBuzz(15);
std::function<void()> printFizz = [](){printf(" fizz ");};
std::function<void()> printBuzz = [](){printf(" buzz ");};
std::function<void()> printFizzBuzz = [](){printf(" fizzbuzz ");};
std::function<void(int)> printNum = [](int x){printf(" %d ", x);};
std::thread th[4];
th[0] = std::thread(&FizzBuzz::fizz, &fizzBuzz, printFizz);
th[1] = std::thread(&FizzBuzz::buzz, &fizzBuzz, printBuzz);
th[2] = std::thread(&FizzBuzz::fizzbuzz, &fizzBuzz, printFizzBuzz);
th[3] = std::thread(&FizzBuzz::number, &fizzBuzz, printNum);
for(auto &ts : th) {
if(ts.joinable()) ts.join();
}
return 0;
}