1. 程式人生 > 其它 >C++ 多執行緒按順序執行函式

C++ 多執行緒按順序執行函式

C++ 多執行緒按順序執行函式的常用操作。

我們提供了一個類:

public class Foo {
  public void first() { print("first"); }
  public void second() { print("second"); }
  public void third() { print("third"); }
}

三個不同的執行緒 A、B、C 將會共用一個 Foo 例項。

一個將會呼叫 first() 方法
一個將會呼叫 second() 方法
還有一個將會呼叫 third() 方法
請設計修改程式,以確保 second() 方法在 first() 方法之後被執行,third() 方法在 second() 方法之後被執行。

法一:訊號量

#include <semaphore.h>
class Foo {
private:
    sem_t firstDone;
    sem_t secondDone;
public:
    Foo() {
        sem_init(&firstDone,0,0);
        sem_init(&secondDone,0,0);
    }

    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        sem_post(&firstDone);
    }

    void second(function<void()> printSecond) {
        sem_wait(&firstDone);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        sem_post(&secondDone);
    }

    void third(function<void()> printThird) {
        sem_wait(&secondDone);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};

互斥鎖:mutex

#include <semaphore.h>
class Foo {
private:
    mutex mtx1;
    mutex mtx2;
public:
    Foo() {
        mtx1.lock();
        mtx2.lock();
    }

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

    void second(function<void()> printSecond) {
        mtx1.lock();
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        mtx1.unlock();
        mtx2.unlock();
    }

    void third(function<void()> printThird) {
        mtx2.lock();
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
        mtx2.unlock();
    }
};

RAII lock_guard, unique_lock

#include <semaphore.h>
class Foo {
private:
    mutex mtx1;
    mutex mtx2;
    unique_lock<mutex> m1lock,m2lock;
public:
    Foo() :m1lock(mtx1,try_to_lock),m2lock(mtx2,try_to_lock){
        
    }

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

    void second(function<void()> printSecond) {
        lock_guard<mutex> guard(mtx1);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        m2lock.unlock();
    }

    void third(function<void()> printThird) {
        lock_guard<mutex> guard(mtx2);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};

條件變數

#include <semaphore.h>
class Foo {
private:
    condition_variable cv;
    mutex mtx;
    int k;
public:
    Foo() {
        k = 0;
    }

    void first(function<void()> printFirst) {
        printFirst();
        k = 1;
        cv.notify_all();
    }

    void second(function<void()> printSecond) {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock,[this](){return k==1;});
        printSecond();
        k=2;
        cv.notify_one();
    }

    void third(function<void()> printThird) {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock,[this](){return k==2;});
        printThird();
    }
};

原子操作

非同步操作

class Foo {
    promise<void> pro1,pro2;
public:
    Foo() {
        
    }

    void first(function<void()> printFirst) {
        printFirst();
        pro1.set_value();
    }

    void second(function<void()> printSecond) {
        pro1.get_future().wait();
        printSecond();
        pro2.set_value();
    }

    void third(function<void()> printThird) {
        pro2.get_future().wait();
        printThird();
    }
};

部落格地址:www.orzlinux.cn