leetcode 交替打印字符串 中等
使用 4 个互斥锁进行线程同步,假设4个锁分别为 a,b,c,d,对应 fizz, buzz, fizzbuzz, number 四个函数.
由于是从 1 开始进行打印,所以初始化时将 a,b,c 这三个锁锁住,只留下 d 作为入口。
接下来有两种方式:
① 先打印当前的数,然后通过下一个数判断对哪个锁进行解锁。。。
② 程序按照固定的方式进行解锁,即 fizz 中解除 b,buzz 解除 c,fizzbuzz 解除 d,number 解除 a。
class FizzBuzz { private: int n; public: FizzBuzz(int n) { this->n = n; mutexFizz.lock(); mutexBuzz.lock(); mutexFB.lock(); } // printFizz() outputs "fizz". void fizz(function<void()> printFizz) { while(cur <= n) { mutexFizz.lock(); if(cur > n) { mutexFizz.unlock(); break; } // 因为到自己的时候, cur 已经可能越界了, 结束线程, 并自行进行解锁 printFizz(); next(); } } // printBuzz() outputs "buzz". void buzz(function<void()> printBuzz) { while(cur <= n) { mutexBuzz.lock(); if(cur > n) { mutexBuzz.unlock(); break; } printBuzz(); next(); } } // printFizzBuzz() outputs "fizzbuzz". void fizzbuzz(function<void()> printFizzBuzz) { while(cur <= n) { mutexFB.lock(); if(cur > n) { mutexFB.unlock(); break; } printFizzBuzz(); next(); } } // printNumber(x) outputs "x", where x is an integer. void number(function<void(int)> printNumber) { while(cur <= n) { mutexNum.lock(); if(cur > n) { mutexNum.unlock(); break; } printNumber(cur); next(); } } private: int cur = 1; mutex mutexFizz, mutexBuzz, mutexFB, mutexNum; void next() { ++ cur; if(cur > n) { // 打印任务结束, 唤醒所有线程进行结束 mutexFB.unlock(); mutexFizz.unlock(); mutexBuzz.unlock(); mutexNum.unlock(); return; } if(cur % 15 == 0) mutexFB.unlock(); else if(cur % 3 == 0) mutexFizz.unlock(); else if(cur % 5 == 0) mutexBuzz.unlock(); else mutexNum.unlock(); } };
class FizzBuzz { private: int n; mutex a, b, c, d; public: FizzBuzz(int n) { this->n = n; b.lock(); c.lock(); d.lock(); } // printFizz() outputs "fizz". void fizz(function<void()> printFizz) { for (int i = 1; i <= n; ++i) { a.lock(); if (i % 3 == 0&&i % 15!=0)printFizz(); b.unlock(); } } // printBuzz() outputs "buzz". void buzz(function<void()> printBuzz) { for (int i = 1; i <=n; ++i) { b.lock(); if (i % 5 == 0&&i%15!=0)printBuzz(); c.unlock(); } } // printFizzBuzz() outputs "fizzbuzz". void fizzbuzz(function<void()> printFizzBuzz) { for (int i = 1; i <= n; ++i) { c.lock(); if (i % 15==0)printFizzBuzz(); d.unlock(); } } // printNumber(x) outputs "x", where x is an integer. void number(function<void(int)> printNumber) { for (int i = 1; i <= n; ++i) { d.lock(); if (i % 3 != 0 && i % 5 != 0)printNumber(i); a.unlock(); } } };