Maison > développement back-end > C++ > le corps du texte

Comment empêcher les erreurs de segmentation dans une file d'attente Thread-Safe C 11 lors de l'utilisation de « std :: condition_variable :: wait_for » ?

DDD
Libérer: 2024-11-01 11:49:30
original
915 Les gens l'ont consulté

How to Prevent Segfaults in a C  11 Thread-Safe Queue When Using `std::condition_variable::wait_for`?

File d'attente thread-safe en C 11

Dans un environnement multithread, il est crucial de garantir que les sections critiques du code sont protégées pour éviter la corruption des données. L’une de ces sections critiques est la gestion des files d’attente de données. Une file d'attente est une structure de données qui suit le principe du « Premier entré, premier sorti » (FIFO). L'implémentation d'une file d'attente thread-safe en C 11 implique l'utilisation de mécanismes de synchronisation tels que des mutex et des variables de condition.

L'extrait de code en question présente une file d'attente thread-safe utilisant std::mutex et std::condition_variable. La méthode enqueue ajoute un élément à la file d'attente tout en maintenant un verrou sur le qMutex pour protéger la file d'attente. Il notifie également tous les threads en attente à l'aide de la variable de condition populatedNotifier.

La méthode dequeue récupère un élément de la file d'attente. Il acquiert un verrou unique sur le qMutex, vérifie si la file d'attente est vide et attend en utilisant la fonction wait_for avec un timeout si nécessaire. Si un fil est informé de nouveaux éléments dans la file d'attente, il quitte l'attente et procède à la récupération et à la suppression d'un élément de la file d'attente.

Cependant, des erreurs de segmentation ont été observées lorsque la file d'attente est vide, indiquant que la fonction wait_for est renvoyée. sans notification. Cela peut se produire en raison d'un réveil parasite.

Pour éviter ce problème, il est conseillé d'inverser la condition de la boucle while. Au lieu d'« attendre que la file d'attente ne soit pas vide », attendez que « la file d'attente soit vide ». Cela garantit que la boucle revérifie le vide de la file d'attente après tout réveil intempestif.

Voici une version révisée de la méthode dequeue :

<code class="cpp">std::string FileQueue::dequeue(const std::chrono::milliseconds&amp; timeout)
{
    std::unique_lock<std::mutex> lock(qMutex);
    while (q.empty()) {
        if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) {
            // Lock may have been released spuriously; recheck condition
            if (q.empty()) {
                return std::string();
            }
            std::string ret = q.front();
            q.pop();
            return ret;
        }
        else {
            return std::string();
        }
    }
    std::string ret = q.front();
    q.pop();
    return ret;
}</code>
Copier après la connexion

Cela garantit que le thread ne continue que lorsque la file d'attente n'est pas vide, évitant ainsi les erreurs de segmentation causées par des réveils parasites.

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!