ホームページ  >  記事  >  バックエンド開発  >  C++ マルチスレッド プログラミングにおけるデッドロックの原因は何ですか?

C++ マルチスレッド プログラミングにおけるデッドロックの原因は何ですか?

WBOY
WBOYオリジナル
2024-06-03 10:05:58891ブラウズ

C++ マルチスレッド プログラミングにおけるデッドロックの主な原因は次のとおりです。 1. ミューテックス ロックの不適切な使用 2. シーケンシャル ロック。実際の戦闘では、複数のスレッドが同じロックのセットを同時に取得しようとし、異なる順序で取得しようとすると、デッドロックが発生する可能性があります。これは、常に同じ順序でロックを取得することで回避できます。

C++ 多线程编程中 deadlocks 的成因是什么?

C++ マルチスレッドプログラミングにおけるデッドロックの原因

デッドロックは、並行プログラミングでよくあるエラーで、1 つ以上のスレッドが別のスレッドのロックの解放を待っているときに発生します。再度ロックを解除してください。これにより、プログラムがスタックし、実行を続行できなくなります。

C++ では、デッドロックは通常、次のような原因で発生します。

  • ミューテックス ロックの不適切な使用: ミューテックス ロックが正しく使用されていない場合、スレッドが同時に同じロックを取得しようとして、デッドロックが発生する可能性があります。
  • 順次ロック: スレッドが複数のロックを取得する必要がある場合、常に同じ順序でこれらのロックを取得する必要があります。そうしないと、あるスレッドが別のスレッドがロックを解放するのを待機し、別のスレッドがそのスレッドが別のロックを解放するのを待機するため、デッドロックが発生する可能性があります。

実践的な例:

次のコードを考えてみましょう:

class BankAccount {
public:
    std::mutex m_mutex; // 互斥锁
    int balance = 0;
};

void transfer(BankAccount &from, BankAccount &to, int amount) {
    std::lock_guard<std::mutex> lock1(from.m_mutex); // 锁定第一个账户
    std::lock_guard<std::mutex> lock2(to.m_mutex); // 锁定第二个账户
    
    // 从第一个账户扣除金额
    from.balance -= amount;
    
    // 将金额添加到第二个账户
    to.balance += amount;
}

この例では、2 つのスレッドが同時に transfer() 関数を呼び出し、異なる口座から同じ口座に送金しようとした場合、死亡が発生します。ロックが発生します。これは、一方のスレッドが最初に最初のアカウントをロックし、次に別のスレッドが 2 番目のアカウントを解放するのを待ち、もう 1 つのスレッドが最初に 2 番目のアカウントをロックし、次に最初のスレッドが最初のアカウントを解放するのを待つためです。

これを回避するには、スレッドは常に同じ順序でロックを取得する必要があります。例:

void transfer(BankAccount &from, BankAccount &to, int amount) {
    // 按照账户 ID 排序账户
    if (from.getId() < to.getId()) {
        std::lock_guard<std::mutex> lock1(from.m_mutex);
        std::lock_guard<std::mutex> lock2(to.m_mutex);
    } else {
        std::lock_guard<std::mutex> lock2(to.m_mutex);
        std::lock_guard<std::mutex> lock1(from.m_mutex);
    }
    
    // 从第一个账户扣除金额
    from.balance -= amount;
    
    // 将金额添加到第二个账户
    to.balance += amount;
}

アカウント ID でアカウントを並べ替え、同じ順序でロックすることで、この問題の発生を防ぐことができます。

以上がC++ マルチスレッド プログラミングにおけるデッドロックの原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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