recursive_mutex
이 들어있는 unique_lock
을 이동할 때 어떤 일이 발생하는지 궁금합니다.unique_lock <recursive_mutex>를 다른 스레드로 이동
특히,이 코드를 찾고 있었어요 :
recursive_mutex g_mutex;
#define TRACE(msg) trace(__FUNCTION__, msg)
void trace(const char* function, const char* message)
{
cout << std::this_thread::get_id() << "\t" << function << "\t" << message << endl;
}
future<void> foo()
{
unique_lock<recursive_mutex> lock(g_mutex);
TRACE("Owns lock");
auto f = std::async(launch::async, [lock = move(lock)]{
TRACE("Entry");
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
this_thread::sleep_for(chrono::seconds(3));
});
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Doesn't own lock!
return f;
}
int main()
{
unique_lock<recursive_mutex> lock(g_mutex);
TRACE("Owns lock");
auto f = foo();
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
f.wait();
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
}
이 샘플 코드의 출력은 나에게 많은 놀라게했다. main()의 unique_lock
은 스레드가 뮤텍스를 릴리스했다는 것을 어떻게 알 수 있습니까? 진짜야?
당신이 뭘 놀라워하는지 명확하지 않습니다. 'own__lock()'이 리턴하는'unique_lock'에 간단한 부울 멤버가 있습니다.이 멤버는 이동 생성자에 의해 예측 가능하고 문서화 된 방식으로 이동됩니다. 'owns_lock()'은 기본 뮤텍스를 건드리지 않습니다. 당신의 프로그램은 정의되지 않은 행동을 보입니다 : 유니크 락이 worker 쓰레드에서 파괴되면'g_mutex.unlock()'을 호출하지만 worker 쓰레드는'g_mutex' 'unlock()'에 대한 필요 조건). –
@IgorTandetnik 감사합니다. 그래서 쓰레드간에'recursive_mutex '의 소유권을 옮기는 것은 불가능합니까? 뮤텍스가 재귀 적이 아닌 경우 'unique_lock'을 움직이면 소유권을 소유자 스레드로 옮길 수 있습니까? –
스레드간에'unique_lock'을 이동하는 것은 전혀 도움이되지 않습니다. 'unique_lock'은'뮤텍스 *'포인터와'bool owns' 플래그에 불과하다는 것을 알 수 있습니다 - 검은 마법은 없습니다. 이동 생성자는 단순히 포인터와 부울을 이동합니다. my_mutex.lock()을 호출 한 스레드와 다른 스레드에서'my_mutex.unlock()'을 호출하면 명시 적으로 또는 간접적으로'unique_lock'을 속여서 수행하는 것과 같이 정의되지 않은 동작을 보입니다. 이것은 모든 뮤텍스의 특징입니다. –