Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah punca kebuntuan dalam pengaturcaraan berbilang benang C++?

Apakah punca kebuntuan dalam pengaturcaraan berbilang benang C++?

WBOY
WBOYasal
2024-06-03 10:05:58930semak imbas

Dalam pengaturcaraan berbilang benang C++, punca utama kebuntuan ialah: 1. Penggunaan kunci mutex yang tidak betul 2. Penguncian berurutan. Dalam pertempuran sebenar, jika beberapa utas cuba memperoleh set kunci yang sama pada masa yang sama dan memperolehnya dalam susunan yang berbeza, kebuntuan mungkin berlaku. Ini boleh dielakkan dengan sentiasa memperoleh kunci dalam susunan yang sama.

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

Punca kebuntuan dalam pengaturcaraan berbilang benang C++

Kebuntuan ialah ralat biasa dalam pengaturcaraan serentak Ia berlaku apabila satu atau lebih utas menunggu utas lain melepaskan kunci sementara utas lain Menunggu yang pertama lepaskan kunci semula. Ini akan menyebabkan program tersekat dan tidak dapat meneruskan pelaksanaan.

Dalam C++, kebuntuan biasanya disebabkan oleh:

  • Penggunaan kunci mutex yang tidak betul: Jika kunci mutex tidak digunakan dengan betul, benang mungkin cuba memperoleh kunci yang sama pada masa yang sama, mengakibatkan kebuntuan.
  • Penguncian berurutan: Jika benang perlu memperoleh berbilang kunci, mereka harus sentiasa memperoleh kunci ini dalam susunan yang sama. Jika tidak, jalan buntu mungkin berlaku kerana satu utas mungkin menunggu untuk satu lagi benang untuk melepaskan kunci, dan satu lagi benang sedang menunggu untuk benang itu untuk melepaskan satu lagi kunci.

Contoh praktikal:

Pertimbangkan kod berikut:

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;
}

Dalam contoh ini, jika dua utas memanggil fungsi transfer() pada masa yang sama, dan mereka cuba memindahkan wang dari akaun berbeza ke akaun yang sama, kematian akan berlaku Kunci. Ini kerana satu urutan pertama akan mengunci akaun pertama dan kemudian menunggu urutan lain untuk melepaskan akaun kedua, dan utas lain akan mengunci akaun kedua terlebih dahulu dan kemudian menunggu urutan pertama mengeluarkan akaun pertama.

Untuk mengelakkan perkara ini, benang hendaklah sentiasa memperoleh kunci dalam susunan yang sama, contohnya:

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;
}

Dengan mengisih akaun mengikut ID akaun dan menguncinya dalam susunan yang sama, kita boleh mengelakkan perkara ini daripada berlaku.

Atas ialah kandungan terperinci Apakah punca kebuntuan dalam pengaturcaraan berbilang benang C++?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn