Write a program that outputs the string representation of numbers from 1 to n, however:
- If the number is divisible by 3, output “fizz”.
- If the number is divisible by 5, output “buzz”.
- If the number is divisible by both 3 and 5, output “fizzbuzz”.
For example, for n = 15
, we output: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz
.
Suppose you are given the following code:
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 }
Implement a multithreaded version of FizzBuzz
with four threads. The same instance of FizzBuzz
will be passed to four different threads:
- Thread A will call
fizz()
to check for divisibility of 3 and outputsfizz
. - Thread B will call
buzz()
to check for divisibility of 5 and outputsbuzz
. - Thread C will call
fizzbuzz()
to check for divisibility of 3 and 5 and outputsfizzbuzz
. - Thread D will call
number()
which should only output the numbers.
Solution:
4 Semaphores
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// Author: Huahua class Semaphore { public: Semaphore (int count = 0): count_(count) {} inline void notify() { unique_lock<std::mutex> lock(mtx_); count_++; cv_.notify_one(); } inline void wait() { unique_lock<std::mutex> lock(mtx_); while (count_ == 0) cv_.wait(lock); count_--; } private: mutex mtx_; condition_variable cv_; int count_; }; class FizzBuzz { private: int n; Semaphore sn; Semaphore s3; Semaphore s5; Semaphore s15; public: FizzBuzz(int n): n(n), sn(1), s3(0), s5(0), s15(0) {} void fizz(function<void()> printFizz) { for (int i = 3; i <= n; i += 3) { if (i % 5 == 0) continue; s3.wait(); printFizz(); sn.notify(); } } void buzz(function<void()> printBuzz) { for (int i = 5; i <= n; i += 5) { if (i % 3 == 0) continue; s5.wait(); printBuzz(); sn.notify(); } } void fizzbuzz(function<void()> printFizzBuzz) { for (int i = 15; i <= n; i += 15) { s15.wait(); printFizzBuzz(); sn.notify(); } } void number(function<void(int)> printNumber) { for (int i = 1; i <= n; ++i) if (i % 15 == 0) { s15.notify(); sn.wait(); } else if (i % 5 == 0) { s5.notify(); sn.wait(); } else if (i % 3 == 0) { s3.notify(); sn.wait(); } else { printNumber(i); } } }; |