leetcode 交替打印字符串 中等

时间:2021-09-20
本文章向大家介绍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();
        }
    }
};

原文地址:https://www.cnblogs.com/rookie-acmer/p/15314323.html