GNU/Linux >> Tutoriels Linux >  >> Linux

Comment affirmer si un std ::mutex est verrouillé ?

Strictement parlant, la question était de vérifier le verrouillage de std::mutex directement. Cependant, si l'encapsuler dans une nouvelle classe est autorisé, c'est très simple :

class mutex :
    public std::mutex
{
public:
#ifndef NDEBUG
    void lock()
    {
        std::mutex::lock();
        m_holder = std::this_thread::get_id(); 
    }
#endif // #ifndef NDEBUG

#ifndef NDEBUG
    void unlock()
    {
        m_holder = std::thread::id();
        std::mutex::unlock();
    }
#endif // #ifndef NDEBUG

#ifndef NDEBUG
    /**
    * @return true iff the mutex is locked by the caller of this method. */
    bool locked_by_caller() const
    {
        return m_holder == std::this_thread::get_id();
    }
#endif // #ifndef NDEBUG

private:
#ifndef NDEBUG
    std::atomic<std::thread::id> m_holder;
#endif // #ifndef NDEBUG
};

Notez ce qui suit :

  1. En mode de publication, cela n'a aucune surcharge sur std::mutex sauf peut-être pour la construction/destruction (ce qui n'est pas un problème pour les objets mutex).
  2. Le m_holder Le membre n'est accessible qu'entre la prise du mutex et sa libération. Ainsi, le mutex lui-même sert de mutex de m_holder . Avec des hypothèses très faibles sur le type std::thread::id , locked_by_caller fonctionnera correctement.
  3. Autres composants STL, par exemple, std::lock_guard sont des modèles, ils fonctionnent donc bien avec cette nouvelle classe.

std::unique_lock<L> a owns_lock fonction membre (équivalent de is_locked comme tu dis).

std::mutex gmtx;
std::unique_lock<std::mutex> glock(gmtx, std::defer_lock);

void alpha(void) {
   std::lock_guard<decltype(glock)> g(glock);
   beta(void);
   // some other work
}
void beta(void) {
   assert(glock.owns_lock()); // or just assert(glock);
   // some real work
}

MODIF : Dans cette solution, toutes les opérations de verrouillage doivent être effectuées via unique_lock glock non mutex "brut" gmtx . Par exemple, alpha la fonction membre est réécrite avec lock_guard<unique_lock<mutex>> (ou simplement lock_guard<decltype(glock)> ).


Vous pouvez simplement utiliser un recursive_mutex , qui peut être verrouillé plusieurs fois sur le même thread. Remarque :Si c'était mon code, je le restructurerais pour ne pas avoir besoin d'un recursive_mutex , mais cela résoudra votre problème.


Linux
  1. Comment mettre à niveau Ubuntu 20.04 vers Ubuntu 21.04

  2. Comment utiliser les exemples de verrouillage C Mutex pour la synchronisation des threads Linux

  3. Comment puis-je grep récursivement?

  4. Comment savoir si l'insertion de std ::map a réussi ou échoué ?

  5. Comment obtenir l'heure UTC

Comment construire un Flatpak

Comment effectuer une recherche dans Nano

Comment installer OmniOS ce

Comment installer FreeNAS 11.1

Comment grep \n dans le fichier

Comment puis-je répertorier tous les utilisateurs verrouillés sous Linux ?