1. 程式人生 > 其它 >leetcode 交替列印字串 中等

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();
        }
    }
};