Maison  >  Article  >  développement back-end  >  Quelles sont les causes des blocages dans la programmation multithread C++ ?

Quelles sont les causes des blocages dans la programmation multithread C++ ?

WBOY
WBOYoriginal
2024-06-03 10:05:58894parcourir

Dans la programmation multithread C++, les principales causes de blocage sont : 1. Une mauvaise utilisation des verrous mutex ; 2. Le verrouillage séquentiel ; En combat réel, si plusieurs threads tentent d'acquérir le même ensemble de verrous en même temps et dans des ordres différents, un blocage peut se produire. Cela peut être évité en acquérant toujours les serrures dans le même ordre.

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

Causes du blocage dans la programmation multithread C++

Le blocage est une erreur courante dans la programmation simultanée. Il se produit lorsqu'un ou plusieurs threads attendent qu'un autre thread libère un verrou tandis qu'un autre thread attend que le premier le fasse. relâchez à nouveau le verrou. Cela entraînera le blocage du programme et l’incapacité de poursuivre son exécution.

En C++, les blocages sont généralement causés par :

  • Une mauvaise utilisation des verrous mutex : Si les verrous mutex ne sont pas utilisés correctement, les threads peuvent essayer d'acquérir le même verrou en même temps, entraînant un blocage.
  • Verrouillage séquentiel : Si les threads doivent acquérir plusieurs verrous, ils doivent toujours acquérir ces verrous dans le même ordre. Sinon, un blocage peut survenir car un thread peut attendre qu'un autre thread libère un verrou, et un autre thread attend que ce thread libère un autre verrou.

Exemple pratique :

Considérez le code suivant :

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

Dans cet exemple, si deux threads appellent la fonction transfer() en même temps et tentent de transférer de l'argent de différents comptes vers le même compte, un décès se produira Lock. En effet, un thread verrouillera d'abord le premier compte, puis attendra qu'un autre thread libère le deuxième compte, et l'autre thread verrouillera d'abord le deuxième compte, puis attendra que le premier thread libère le premier compte.

Pour éviter cela, les fils de discussion doivent toujours acquérir les verrous dans le même ordre, par exemple :

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

En triant les comptes par ID de compte et en les verrouillant dans le même ordre, nous pouvons empêcher que cela se produise.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn