У меня есть случай, когда решения моего алгоритма основаны на глубине общего std::recursive_mutex
,
#include <iostream>
#include <mutex>
#include <thread>
int g_i = 0;
std::recursive_mutex g_i_mutex;
void bar() {
std::lock_guard<std::recursive_mutex> lock(g_i_mutex);
switch (get_counter(g_i_mutex)) { // some way to find the number of owners
case 1: std::cout << "depth 1\n"; break;
case 2: std::cout << "depth 2\n"; break;
default:;
}
}
void foo() {
std::lock_guard<std::recursive_mutex> lock(g_i_mutex);
std::cout << "hello\n";
bar();
}
int main() {
foo(); //print hello then depth 2
bar(); //print depth 1
}
Я читал, что рекурсивные мьютексы содержат некоторый счетчик использования, и они увеличивают и уменьшают его с каждым вызовом блокировки / разблокировки. Есть ли способ получить доступ к этой информации?
нет ты не можешь.
Это невозможно, потому что упомянутый вами счетчик является решением для реализации, он может существовать или не существовать. Если вы знали, что конкретная реализация Стандартной библиотеки использует счетчик, вы можете использовать некоторую магию (арифметику указателей и приведение типов), но это будет неопределенное поведение.
При этом, ничто не запрещает вам определить свой собственный recursive_mutex
:
#include <iostream>
#include <mutex>
#include <atomic>
class recursive_mutex
{
std::recursive_mutex _mutex;
std::atomic<unsigned> _counter;
public:
recursive_mutex() : _mutex(), _counter(0) {}
recursive_mutex(recursive_mutex&) = delete;
void operator=(recursive_mutex&) = delete;
void lock() { _mutex.lock(); ++_counter; }
bool try_lock() { bool result = _mutex.try_lock(); _counter += result; return result; }
void unlock() { --_counter; _mutex.unlock(); }
unsigned counter() { return _counter; }
};
int main() {
recursive_mutex m;
m.lock();
m.lock();
std::cout << m.counter() << "\n";
m.unlock();
std::cout << m.counter() << "\n";
m.unlock();
}
2
1
Других решений пока нет …