GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo afirmar si un std::mutex está bloqueado?

Estrictamente hablando, la pregunta era sobre verificar el bloqueo de std::mutex directamente. Sin embargo, si se permite encapsularlo en una nueva clase, es muy fácil hacerlo:

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

Tenga en cuenta lo siguiente:

  1. En el modo de lanzamiento, esto tiene una sobrecarga cero sobre std::mutex excepto posiblemente para construcción/destrucción (que no es un problema para objetos mutex).
  2. El m_holder solo se accede al miembro entre tomar el mutex y liberarlo. Por lo tanto, el mutex en sí mismo sirve como mutex de m_holder . Con suposiciones muy débiles sobre el tipo std::thread::id , locked_by_caller funcionará correctamente.
  3. Otros componentes STL, por ejemplo, std::lock_guard son plantillas, por lo que funcionan bien con esta nueva clase.

std::unique_lock<L> tiene owns_lock función miembro (equivalente a is_locked como dices).

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
}

EDITAR: En esta solución, todas las operaciones de bloqueo deben realizarse a través de unique_lock glock no mutex 'en bruto' gmtx . Por ejemplo, alpha la función miembro se reescribe con lock_guard<unique_lock<mutex>> (o simplemente lock_guard<decltype(glock)> ).


Podrías usar un recursive_mutex , que se puede bloquear varias veces en el mismo subproceso. Nota:si fuera mi código, lo reestructuraría para no necesitar un recursive_mutex , pero solucionará su problema.


Linux
  1. Cómo desbloquear una IP en CSF

  2. Cómo:bloquear cPanel y WHM a través de cPHulk

  3. Cómo actualizar Ubuntu 20.04 a Ubuntu 21.04

  4. Cómo usar ejemplos de bloqueo C Mutex para la sincronización de subprocesos de Linux

  5. ¿Cómo crear un directorio temporal en C++?

Cómo construir un paquete plano

Cómo buscar en Nano

Cómo instalar OmniOS ce

Cómo instalar FreeNAS 11.1

Cómo grep \n en el archivo

Cómo redirigir la salida del programa como su entrada