2016-07-20 11 views
5

두 개의 boost :: scoped_locks를 동시에 보유하면 어떤 문제가 있는지 알고 싶습니다. 잠금은 다른 뮤텍스를 잠그고 있습니다. 다음 예제를 고려하십시오.동시에 두 개의 뮤텍스 잠금 유지

void foo1() 
{ 
    boost::recursive_mutex::scoped_lock lock(mutex1); 
    foo2(); 
} 

void foo2() 
{ 
    boost::recursive_mutex::scoped_lock lock(mutex2); 
} 

이것이 교착 상태가 발생하지 않아야 함을 알고 있습니다. 그러나 다른 문제가 있습니까? 어쩌면 스레드가 너무 오랫동안 잠자기가 될 수 있습니까?

답변

5

두 개 이상의 잠금 장치를 들고 있으면 자체에 문제가 있습니다. 문제가 있습니다.

다른 스레드가 동일한 잠금을 다른 순서로 얻으려고 시도 할 때 문제가 발생하여 ABBA 교착 상태가 발생합니다. 스레드 1은 AB을 잠근 다음 스레드 2는 B을 잠 그려고하고 A을 잠그고 양쪽 모두가 차단되도록 잠급니다 (잠금 인터리빙으로 인해 t1은 A을 잠그고 t2는 B을 잠근 다음 다른 블록을 잠그려고 차단합니다). 계속할 수 있으려면 잠금 장치 중 하나를 해제하고 다른 장치는 계속 잠금을 해제 할 수 있도록 잠금 장치를 해제하십시오.

따라서 일반적인 경험 법칙은 다음과 같습니다. 하나 이상의 잠금 장치를 가져와야하는 경우 모든 스레드가 항상 같은 순서로 해당 잠금을 얻으려고하는지 확인하십시오.

+0

답변 해 주셔서 감사합니다. :) –

+0

계속하려면 잠금 순서를 보장하는 한 가지 방법은 뮤텍스/잠금 주위에 경량 래퍼를 놓은 다음 레이어 i의 생성자에 레이어 (i-1)의 고정 된 참조를 가져 오는 것입니다. 그런 다음 다른 방법으로는 만들 수 없습니다. 또는 C++ 17을 사용하고 동시에 잠금을 해제하십시오. – lorro

+0

@lorro 문제를 해결할 수있는 방법이 여러 가지 있음을 잘 알고 있습니다. 그러나 문제 구현이 현명하게 해결되는 방법에 대한 조언을 제공하는 것이 아니라 잠재 문제가 무엇인지 지적하고 문제를 피하는 일반적인 규칙을 지적하기 위해 노력했습니다. 구현은 독자를위한 운동으로 남았습니다. :-) –

5

이면 반대 순서로 두 뮤텍스를 획득하면 교착 상태가 발생합니다. 이 시점에서

        mutex1 mutex2 
Time Thread A  Thread B owner owner 
    0  foo1()      A 
    1     bar1()  A  B 
    2     bar2()  A  B 
    3  foo2()      A  B 

이 교착되는 & B 스레드 :로 인터리브

void bar1() { 
    boost::recursive_mutex::scoped_lock lock(mutex2); 
    bar2(); 
} 

void bar2() { 
    boost::recursive_mutex::scoped_lock lock(mutex1); 
} 

두 스레드가 교착 상태 것이다 다음과 같습니다. 나는 기본 OS가 그래도 boost이 이것에 대한 보호를 제공한다고 생각하지 않는다.

+0

답변 해 주셔서 감사합니다! :) –