GNU/Linux >> Linux Esercitazione >  >> Linux

Come affermare se uno std::mutex è bloccato?

A rigor di termini, la domanda riguardava il controllo del blocco di std::mutex direttamente. Tuttavia, se è consentito incapsularlo in una nuova classe, è molto semplice farlo:

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

Nota quanto segue:

  1. Nella modalità di rilascio, questo ha un sovraccarico pari a zero rispetto a std::mutex tranne possibilmente per la costruzione/distruzione (che non è un problema per gli oggetti mutex).
  2. Il m_holder membro è accessibile solo tra l'acquisizione del mutex e il suo rilascio. Così il mutex stesso funge da mutex di m_holder . Con ipotesi molto deboli sul tipo std::thread::id , locked_by_caller funzionerà correttamente.
  3. Altri componenti STL, ad esempio std::lock_guard sono modelli, quindi funzionano bene con questa nuova classe.

std::unique_lock<L> ha owns_lock funzione membro (equivalente di is_locked come dici tu).

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
}

MODIFICA: In questa soluzione, tutte le operazioni di blocco dovrebbero essere eseguite tramite unique_lock glock mutex non 'raw' gmtx . Ad esempio, alpha la funzione membro viene riscritta con lock_guard<unique_lock<mutex>> (o semplicemente lock_guard<decltype(glock)> ).


Potresti semplicemente usare un recursive_mutex , che può essere bloccato più volte sullo stesso thread. Nota:se fosse il mio codice, lo ristrutturerei in modo da non aver bisogno di un recursive_mutex , ma risolverà il tuo problema.


Linux
  1. Come utilizzare gli esempi di blocco Mutex C per la sincronizzazione dei thread di Linux

  2. Come faccio a grep in modo ricorsivo?

  3. pthreads mutex vs semaforo

  4. Come creare una directory temporanea in C++?

  5. Come implementare readlink per trovare il percorso

Come costruire un Flatpak

Come cercare in Nano

Come installare OmniOS ce

Come installare FreeNAS 11.1

Come faccio a sapere se std::map insert è riuscito o meno?

Come posso elencare tutti gli utenti bloccati in Linux?