leetcode 交替列印字串 中等
阿新 • • 發佈:2021-09-22
使用 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(); } } };