ホームページ >バックエンド開発 >C++ >C++ 同時プログラミングにおけるデッドロックとデッドロックを回避する戦略?

C++ 同時プログラミングにおけるデッドロックとデッドロックを回避する戦略?

WBOY
WBOYオリジナル
2024-06-02 10:44:57730ブラウズ

デッドロックは、他のスレッドがリソースを解放するのを待っている間にスレッドが循環待機状態に陥ったときに発生します。デッドロックを回避する戦略は次のとおりです。 ループ待機の回避 リソースの秩序ある使用 タイムアウト戦略 食事の哲学者問題では、箸のリソースを秩序正しく使用する (左側の箸が最初) ことで、デッドロックの問題が解決されます。

C++ 并发编程中死锁及避免死锁的策略?

C++ 同時プログラミングにおけるデッドロックとデッドロックを回避する戦略

デッドロックとは何ですか?

同時プログラミングでは、複数のスレッドが他のスレッドが同時にリソースを解放するのを待機すると、デッドロックが発生します。これにより、スレッドが無期限にブロックされ、実行を続行できなくなります。

デッドロックを回避するための戦略

デッドロックを回避するにはいくつかの戦略があります:

  • 循環待機を避ける: 他のスレッドがリソースを解放するのを待って、スレッドが循環待機関係を形成しないようにします。
  • リソースの秩序ある使用: すべてのリソースに対して固定の取得順序を確立し、すべてのスレッドがこの順序でリソースを取得するように強制します。
  • タイムアウト戦略: リソースを取得するためのタイムアウトを設定します。タイムアウト期間内にスレッドがリソースを取得できない場合、リソースは解放されます。

実践例: 食事の哲学者問題

食事の哲学者問題は、古典的なデッドロック問題です。 5 人の哲学者が円卓の周りに座っており、それぞれが箸を持っています。いつでも左右2本の箸を使って食事ができますが、同時に持つことができるのは1本だけです。すべての哲学者が同時に左の箸を取ると、全員が行き詰まってしまいます。

この問題を解決するには、リソースの順序付けられた使用戦略を使用できます:

// 筷子类
class Chopstick {
public:
    Chopstick() {
        m_mutex = new std::mutex;
    }

    ~Chopstick() {
        delete m_mutex;
    }

    void lock() {
        m_mutex->lock();
    }

    void unlock() {
        m_mutex->unlock();
    }

private:
    std::mutex* m_mutex;
};

// 哲学家类
class Philosopher {
public:
    Philosopher(int id, Chopstick* left, Chopstick* right)
        : m_id(id), m_left(left), m_right(right) {}

    void dine() {
        while (true) {
            // 获取左边的筷子
            m_left->lock();

            // 获取右边的筷子
            m_right->lock();

            // 进餐
            std::cout << "哲学家 " << m_id << " 正在进餐" << std::endl;

            // 放下右边的筷子
            m_right->unlock();

            // 放下左边的筷子
            m_left->unlock();
        }
    }

private:
    int m_id;
    Chopstick* m_left;
    Chopstick* m_right;
};

int main() {
    // 创建 5 根筷子
    Chopstick chopsticks[5];

    // 创建 5 个哲学家
    Philosopher philosophers[5] = {
        Philosopher(0, &chopsticks[0], &chopsticks[4]),
        Philosopher(1, &chopsticks[1], &chopsticks[0]),
        Philosopher(2, &chopsticks[2], &chopsticks[1]),
        Philosopher(3, &chopsticks[3], &chopsticks[2]),
        Philosopher(4, &chopsticks[4], &chopsticks[3])
    };

    // 启动哲学家线程
    std::thread threads[5]; 
    for (int i = 0; i < 5; i++) {
        threads[i] = std::thread(&Philosopher::dine, &philosophers[i]);
    }

    // 等待哲学家线程结束
    for (int i = 0; i < 5; i++) {
        threads[i].join();
    }

    return 0;
}

この例では、各箸に対して std::mutexミューテックスを作成し、一度に 1 人の哲学者だけが箸にアクセスできるようにします。箸を順番に並べることで行き詰まりを避けることができます。

以上がC++ 同時プログラミングにおけるデッドロックとデッドロックを回避する戦略?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。