Přísně vzato, otázka se týkala kontroly uzamčení std::mutex
přímo. Pokud je však povoleno zapouzdření do nové třídy, je to velmi snadné:
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
};
Všimněte si následujícího:
- V režimu uvolnění má nulovou režii nad
std::mutex
možná kromě konstrukce/destrukce (což u mutexových objektů není problém). m_holder
člen je přístupný pouze mezi převzetím mutexu a jeho uvolněním. Samotný mutex tedy slouží jako mutexm_holder
. S velmi slabými předpoklady o typustd::thread::id
,locked_by_caller
bude fungovat správně.- Další komponenty STL, např.
std::lock_guard
jsou šablony, takže s touto novou třídou dobře fungují.
std::unique_lock<L>
má owns_lock
členská funkce (ekvivalent is_locked
jak říkáš).
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
}
UPRAVIT: V tomto řešení by všechny operace uzamčení měly být prováděny pomocí unique_lock glock
nikoli „raw“ mutex gmtx
. Například alpha
členská funkce je přepsána pomocí lock_guard<unique_lock<mutex>>
(nebo jednoduše lock_guard<decltype(glock)>
).
Stačí použít recursive_mutex
, které lze uzamknout vícekrát ve stejném vláknu. Poznámka:Pokud by to byl můj kód, restrukturalizoval bych ho tak, že nepotřebuji recursive_mutex
, ale vyřeší to váš problém.
IntelliJ IDEA (Linux):Přejít na začátek/konec řádku
Připojení SMTP serveru PHPMailer GoDaddy zamítnuto