leetcode 多线程编程

C++多线程学习博客推荐

1    C++11多线程编程----初识

2    c++11多线程编程(二)——理解线程类的构造函数

3    c++11多线程编程(三)——竞争条件与互斥锁

4    c++11多线程编程(四)——死锁(Dead Lock)

5    c++11多线程编程(五)——unique_lock

6    c++11多线程编程(六)——条件变量(Condition Variable)

7   Thread类学习

 

按序打印

题目链接:https://leetcode-cn.com/problems/print-in-order/

leetcode 多线程编程_第1张图片

leetcode 多线程编程_第2张图片

法一  mutex

class Foo {
public:
    Foo() {
        mu1.lock();
        mu2.lock();
    }

    void first(function printFirst) {
               
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        mu1.unlock();
    }

    void second(function printSecond) {
        lock_guard guard(mu1);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        mu2.unlock();
    }

    void third(function printThird) {
        lock_guard guard(mu2);
        lock_guard guard2(mu1);
        
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
private:
        std::mutex mu1,mu2;
    
};

可以看作是2把锁,初始时都上锁,printFirst在任何时候可执行。执行结束后开锁1

printSecond只有在锁1开锁后才可以执行,执行时锁锁1,执行结束后开锁2,自动开锁1

printThird只有在锁2开锁后,锁1开锁后才可以执行,执行时锁锁1和2,执行结束后自动开锁1和2.  注意这里上锁不可以先1后2,可能发生死锁。

或者

class Foo {
public:
    Foo() {
        mu1.lock();
        mu2.lock();
    }

    void first(function printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        mu1.unlock();
    }

    void second(function printSecond) {
        mu1.lock();
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        mu2.unlock();
    }

    void third(function printThird) {
        mu2.lock();
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
private:
    std::mutex mu1,mu2;
};

第二个更好点

法二  condition_variable+unique_lock

class Foo {
public:
    Foo() {
        
    }

    void first(function printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        counter+=1;
        cond1.notify_one();
    }

    void second(function printSecond) {
        unique_lock lk(mu);
        cond1.wait(lk,[this](){return counter==2;});
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        counter+=1;
        cond2.notify_one();
    }

    void third(function printThird) {
        unique_lock lk(mu);
        cond2.wait(lk,[this](){return counter==3;});
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
private:
    std::mutex mu;
    std::condition_variable cond1;
    std::condition_variable cond2;
    int counter=1;
};

wait的第二个参数是一个lambda函数

交替打印FooBar

题目链接:https://leetcode-cn.com/problems/print-foobar-alternately/

leetcode 多线程编程_第3张图片

法一 mutex

class FooBar {
private:
    int n;
    std::mutex mu1,mu2;

public:
    FooBar(int n) {
        this->n = n;
        mu2.lock();
    }

    void foo(function printFoo) {
        
        for (int i = 0; i < n; i++) {
            mu1.lock();
        	// printFoo() outputs "foo". Do not change or remove this line.
        	printFoo();
            mu2.unlock();
        }
    }

    void bar(function printBar) {
        
        for (int i = 0; i < n; i++) {
            mu2.lock();
        	// printBar() outputs "bar". Do not change or remove this line.
        	printBar();
            mu1.unlock();
        }
    }
};

法二 condition_variable+unique_lock

class FooBar {
private:
    int n;
    std::condition_variable cond1,cond2;
    std::mutex mu;
    bool var=false;

public:
    FooBar(int n) {
        this->n = n;
    }

    void foo(function printFoo) {
        
        for (int i = 0; i < n; i++) {
            unique_lock lk(mu);
            cond1.wait(lk,[this](){return !var;});
        	// printFoo() outputs "foo". Do not change or remove this line.
        	printFoo();
            var=true;
            cond2.notify_one();
        }
    }

    void bar(function printBar) {
        
        for (int i = 0; i < n; i++) {
            unique_lock lk(mu);
            cond2.wait(lk,[this](){return var;});
        	// printBar() outputs "bar". Do not change or remove this line.
        	printBar();
            var=false;
            cond1.notify_one();
        }
    }
};

注意有一个bool值。

打印零与奇偶数

题目链接:https://leetcode-cn.com/problems/print-zero-even-odd/

leetcode 多线程编程_第4张图片

法一 mutex

class ZeroEvenOdd {
private:
    int n;
    std::mutex mu1,mu2,mu3;

public:
    ZeroEvenOdd(int n) {
        this->n = n;
        mu2.lock();
        mu3.lock();
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero(function printNumber) {
        for(int i=1;i<=n;i++)
        {
            mu1.lock();
            printNumber(0);
            //奇数
            if(i%2)
                mu3.unlock();
            //偶数
            else
                mu2.unlock();
        }
    }

    void even(function printNumber) {
        for(int i=2;i<=n;i+=2)
        {
            mu2.lock();
            printNumber(i);
            mu1.unlock();
        }
    }

    void odd(function printNumber) {
        for(int i=1;i<=n;i+=2)
        {
            mu3.lock();
            printNumber(i);
            mu1.unlock();
        }
    }
};

法二 condition_variable+unique_lock

class ZeroEvenOdd {
private:
    int n;
    std::mutex mu;
    std::condition_variable cv_zero,cv_odd,cv_even;
    bool bzero,bodd;
public:
    ZeroEvenOdd(int n) {
        this->n = n;
        bzero=true;
        bodd=false;
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero(function printNumber) {
        unique_lock lk(mu);
        for(int i=1;i<=n;i++)
        {
            cv_zero.wait(lk,[this](){return bzero;});
            printNumber(0);
            //奇数
            if(i%2)
            {
                cv_odd.notify_one();
                bodd=true;
            }
            else
                cv_even.notify_one();
            bzero=false;
        }
        
    }

    void even(function printNumber) {
        unique_lock lk(mu);
        for(int i=2;i<=n;i+=2)
        {
            cv_even.wait(lk,[this](){return !bzero&&!bodd;});
            printNumber(i);
            bzero=true;
            bodd=true;
            cv_zero.notify_one();
        }
    }

    void odd(function printNumber) {
        unique_lock lk(mu);
        for(int i=1;i<=n;i+=2)
        {
            cv_odd.wait(lk,[this](){return !bzero&&bodd;});
            printNumber(i);
            bzero=true;
            bodd=false;
            cv_zero.notify_one();

        }
    }
};

注意那2个布尔值。

H2O生成

题目链接:https://leetcode-cn.com/problems/building-h2o/

leetcode 多线程编程_第5张图片

 condition_variable+unique_lock

class H2O {
public:
    H2O() {
        
    }

    void hydrogen(function releaseHydrogen) {
        
        // releaseHydrogen() outputs "H". Do not change or remove this line.
        
        std::unique_lock lk(m);
        

        cv.wait(lk, [this](){return h_count <2;});
        releaseHydrogen();
        ++h_count;
        if (h_count == 2 && o_count == 1){
            o_count = 0;
            h_count = 0;
        }
        if(h_count==2)
            cv.notify_all();
    }

    void oxygen(function releaseOxygen) {
        
        // releaseOxygen() outputs "O". Do not change or remove this line.
        std::unique_lock lk(m);
        cv.wait(lk, [this](){return o_count <1&&h_count==2;});
        releaseOxygen();
        ++o_count;
        if (h_count == 2 && o_count == 1){
            o_count = 0;
            h_count = 0;
        }
        cv.notify_one();
    }
    
    private:
    
    std::mutex m;
    std::condition_variable cv;
    int o_count = 0;
    int h_count = 0;
};

 

 

你可能感兴趣的:(leetcode)