GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara menegaskan jika std::mutex dikunci?

Sebenarnya, pertanyaannya adalah tentang memeriksa penguncian std::mutex secara langsung. Namun, jika mengenkapsulasinya di kelas baru diperbolehkan, sangat mudah melakukannya:

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

Perhatikan hal berikut:

  1. Dalam mode rilis, ini memiliki overhead nol di atas std::mutex kecuali mungkin untuk konstruksi/penghancuran (yang bukan masalah untuk objek mutex).
  2. m_holder anggota hanya diakses antara mengambil mutex dan melepaskannya. Jadi mutex itu sendiri berfungsi sebagai mutex dari m_holder . Dengan asumsi yang sangat lemah pada tipe std::thread::id , locked_by_caller akan bekerja dengan benar.
  3. Komponen STL lainnya, mis., std::lock_guard adalah template, sehingga berfungsi baik dengan kelas baru ini.

std::unique_lock<L> memiliki owns_lock fungsi anggota (setara dengan is_locked seperti yang Anda katakan).

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
}

EDIT: Dalam solusi ini, semua operasi kunci harus dilakukan melalui unique_lock glock bukan mutex 'mentah' gmtx . Misalnya, alpha fungsi anggota ditulis ulang dengan lock_guard<unique_lock<mutex>> (atau cukup lock_guard<decltype(glock)> ).


Anda bisa menggunakan recursive_mutex , yang dapat dikunci beberapa kali di utas yang sama. Catatan:Jika itu adalah kode saya, saya akan menyusun ulang sehingga saya tidak memerlukan recursive_mutex , tetapi itu akan mengatasi masalah Anda.


Linux
  1. Bagaimana Cara Membuka Kunci File Rar Kata Sandi yang Terkunci Tanpa Mengetahui Kata Sandi?

  2. Cara Meningkatkan Ubuntu 20.04 ke Ubuntu 21.04

  3. Cara Menggunakan Contoh Kunci C Mutex untuk Sinkronisasi Utas Linux

  1. Bagaimana cara saya grep secara rekursif?

  2. Bagaimana saya tahu jika std::map insert berhasil atau gagal?

  3. Bagaimana menerapkan readlink untuk menemukan jalan

  1. Cara kerja Hexdump

  2. Cara grep \n dalam file

  3. Cara mengarahkan output program sebagai inputnya