Maison  >  Article  >  développement back-end  >  Pourquoi est-ce que j'obtiens des erreurs de segment lorsque j'utilise une variable de condition pour rechercher une file d'attente vide en C ?

Pourquoi est-ce que j'obtiens des erreurs de segment lorsque j'utilise une variable de condition pour rechercher une file d'attente vide en C ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-31 21:14:29656parcourir

Why Am I Getting Segfaults When Using a Condition Variable to Check for an Empty Queue in C  ?

File d'attente thread-safe C 11 : confusion sur l'utilisation des variables de condition

Dans votre code, vous avez implémenté une file d'attente thread-safe à l'aide d'un mutex et une variable de condition. Cependant, vous rencontrez des erreurs de segmentation occasionnelles dans le bloc de code contrôlé par la variable de condition. Plus précisément, vous remarquez que les erreurs de segmentation se produisent lorsque la file d'attente est vide, ce qui semble contre-intuitif car la variable de condition est destinée à signaler la disponibilité de nouveaux éléments dans la file d'attente.

Utilisation incorrecte de la variable de condition

Votre incompréhension vient d'une mauvaise utilisation de la variable de condition. Le but d'une variable de condition est de signaler un changement dans un état partagé, dans lequel d'autres threads peuvent ensuite réagir à ce changement. Cependant, dans votre code, vous utilisez la variable condition pour attendre qu'une condition spécifique (la file d'attente étant vide) devienne fausse. Ceci est incorrect car lorsque la condition devient fausse (c'est-à-dire que la file d'attente n'est plus vide), le thread se réveille, mais il n'est pas garanti que la condition reste fausse (c'est-à-dire que la file d'attente peut être redevenue vide entre-temps) .

Utilisation appropriée des variables de condition

La bonne façon d'utiliser une variable de condition est d'avoir une boucle qui vérifie la condition (dans ce cas, si la file d'attente est vide ) et entre dans un état d'attente si la condition n'est pas remplie. Lorsque la condition est signalée, le thread se réveille, mais il revérifie immédiatement la condition avant de continuer. Cela garantit que le thread n'effectue l'opération souhaitée que si la condition est toujours vraie au réveil.

Implémentation alternative

Voici une implémentation alternative d'un thread-safe file d'attente qui résout le problème :

<code class="cpp">template <class T>
class SafeQueue {
public:
  SafeQueue() : q(), m(), cv() {}

  void enqueue(T t) {
    std::lock_guard<std::mutex> lock(m);
    q.push(t);
    cv.notify_one();
  }

  T dequeue() {
    std::unique_lock<std::mutex> lock(m);
    while (q.empty()) cv.wait(lock);
    T val = q.front();
    q.pop();
    return val;
  }

private:
  std::queue<T> q;
  mutable std::mutex m;
  std::condition_variable cv;
};</code>

Dans cette implémentation, la variable de condition est correctement utilisée pour attendre que la condition de la file d'attente soit vide (ou non vide pour la méthode enqueue) devienne fausse. Le thread n'effectuera l'opération souhaitée (retirer un élément de la file d'attente) que si la file d'attente n'est pas vide après le réveil.

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