多线程编程,交替打印字符串
题目描述:编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:
如果这个数字可以被 3 整除,输出 “fizz”。
如果这个数字可以被 5 整除,输出 “buzz”。
如果这个数字可以同时被 3 和 5 整除,输出 “fizzbuzz”。
例如,当 n = 15,输出: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz。
假设有这么一个类:
class FizzBuzz {
public FizzBuzz(int n) { … } // constructor
public void fizz(printFizz) { … } // only output “fizz”
public void buzz(printBuzz) { … } // only output “buzz”
public void fizzbuzz(printFizzBuzz) { … } // only output “fizzbuzz”
public void number(printNumber) { … } // only output the numbers
}
请你实现一个有四个线程的多线程版 FizzBuzz, 同一个 FizzBuzz 实例会被如下四个线程使用:
线程A将调用 fizz() 来判断是否能被 3 整除,如果可以,则输出 fizz。
线程B将调用 buzz() 来判断是否能被 5 整除,如果可以,则输出 buzz。
线程C将调用 fizzbuzz() 来判断是否同时能被 3 和 5 整除,如果可以,则输出 fizzbuzz。
线程D将调用 number() 来实现输出既不能被 3 整除也不能被 5 整除的数字。
(就是进程同步,pv操作)
代码:
#include <cstdio>
#include <functional>
#include <vector>
#include <semaphore.h>
#include <thread>
using std::function;
class FizzBuzz {
private:
int n;
int cur;
sem_t fizz_;
sem_t buzz_;
sem_t fbzz_;
sem_t num_;
public:
FizzBuzz(int n) {
this->n = n;
cur = 0;
sem_init(&fizz_, 0, 0);
sem_init(&buzz_, 0, 0);
sem_init(&fbzz_, 0, 0);
sem_init(&num_, 0, 1);
}
void fizz(function<void()> printFizz) {
while (cur <= n) {
sem_wait(&fizz_);
if (cur > n)
break;
printFizz();
sem_post(&num_);
//cur += 2;
}
}
// printBuzz() outputs "buzz".
void buzz(function<void()> printBuzz) {
while (cur <= n) {
sem_wait(&buzz_);
if (cur > n)
break;
printBuzz();
sem_post(&num_);
}
}
// printFizzBuzz() outputs "fizzbuzz".
void fizzbuzz(function<void()> printFizzBuzz) {
while (cur <= n) {
sem_wait(&fbzz_);
if (cur > n)
break;
printFizzBuzz();
sem_post(&num_);
}
}
// printNumber(x) outputs "x", where x is an integer.
void number(function<void(int)> printNumber) {
while (cur <= n) {
sem_wait(&num_);
cur++;
if (cur > n)
break;
if (cur % 3 == 0 && cur % 5 == 0) {
sem_post(&fbzz_);
}
else if (cur % 3 == 0)
sem_post(&fizz_);
else if (cur % 5 == 0)
sem_post(&buzz_);
else {
printNumber(cur);
sem_post(&num_);
}
}
//到这一步,cur>n,唤醒其余进程自杀
sem_post(&fizz_);
sem_post(&buzz_);
sem_post(&fbzz_);
}
};
int main()
{
//测试代码:
FizzBuzz fb(15);
function<void()> printfizz = []() {printf("fizz");};
function<void()> printbuzz = []() {printf("fizz"); };
function<void()> printfbzz = []() {printf("fizz"); };
function<void(int)> printnum = [](int num) {printf("%d",num); };
std::vector<std::thread> threads;
threads.push_back(std::thread(&FizzBuzz::fizz, &fb, printfizz));
threads.push_back(std::thread(&FizzBuzz::buzz, &fb, printbuzz));
threads.push_back(std::thread(&FizzBuzz::fizzbuzz, &fb, printfbzz));
threads.push_back(std::thread(&FizzBuzz::number, &fb, printnum));
for (auto& a : threads) {
if (a.joinable())
a.join();
else
printf("error");
}
return 0;
}