2011-07-27 2 views
0

차단없이 upgrade_lock_unique_lock을 수행하고 싶지만 Boost 소스 코드 (v1.46.1)를 보면 이것이 불가능하다는 것을 알 수 있습니까? 내 접근 방식이 잘못 되었나요?"upgrade_to_unique_lock"을 사용하여 "try_lock"을 수행하는 방법

다른 스레드에서 읽을 수 있도록 잠재적으로 보유 할 수있는 리소스의 읽기 잠금을 먼저 가져 오려고합니다. 그런 다음 쓰기가 가능한지보고 싶습니다. 그렇지 않은 경우 (다른 공유 읽기 잠금이 현재 보유되어 있음) 간단히 나중에 수행합니다.

// No way to specify the boost::try_to_lock object 
explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_): 
    source(&m_),exclusive(move(*source)) 

나는 절차 적으로 완벽하게 비동기 적으로 중간 점 변위 알고리즘을 사용하여 지형 타일 (페이지)를 생성하기 위해 노력하고있어. 이렇게하려면 4 개의 주변 타일 (북쪽, 서쪽, 동쪽, 남쪽)에서 얻은 모서리가있는 대상 지형 타일 (가운데)을 시드해야합니다. 가장자리는 이미 존재하고 이미 완전히 생성 된 이웃에서만 수집됩니다. 구현은 한 번에 하나의 이웃 타일을 차단해야하며 언제든지 생성 될 수 있도록 다른 이웃의 읽기 잠금을 보유하지 않아야합니다. 타일이 생성 될 때 다른 스레드가 이웃에 대한 쓰기 잠금을 가지고 있지 않음을 보장해야합니다. 읽기 잠금은 괜찮습니다. 또한 불필요하게 쓰기 잠금을 기다리는 스레드의 데이지 체인이 없어야합니다. 즉, 거리가 다른 두 개의 타일을 서로 독립적으로 생성 할 수 있어야합니다.

내 구현은 카메라와의 거리를보고 필요에 따라 페이지를 비동기 적으로 요청하는 제 3 자 알고리즘에 따라 다릅니다. 특정 순서없이 페이지/타일에 대해 최대 16 개의 비동기 요청을 임의로 만들 수있는 것 같습니다.

+0

'그럼 내가 쓰기에 사용할 수 있는지보고 싶지 않다면 (다른 공유 읽기 잠금이 현재 실행 중입니다.) 간단히 나중에 수행하십시오. 자물쇠를 사용하여 그렇게 할 수는 없습니다. 두 스레드가 동시에 쓰기를 시도하지 못하게하는 이유는 무엇입니까? 나는 대부분의 시스템이 그런 종류의 "시도 된 잠금"을하도록 허용하지 않는다고 믿는다. –

+1

참고 : http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html 저는'upgrade_mutex'의 발명가입니다. 스펙은 부스트 ​​구현에서 엉망이되었습니다. 내가 제공 한 링크는 원하는 것을 수행하는 스펙을 제공합니다. 이 스펙을 다음 C++ 표준 (아마도 기술 보고서로)으로 가져 오려고 노력 중입니다. 이 스팩이 당신에게 좋아 보인다면, 그것에 대해 소란을 피우십시오. 귀하의 국가 기관 대표가 이것이 귀하가 원하는 것임을 알리십시오. 이 군중이 당신이 원하는 것임을 알게하십시오. comp.std.C++에서 군중들이 알도록하십시오. 네가 원하는 것이 아니라면 알려줘. –

+0

이 리소스로 무엇을하고 있습니까? 뭔가를하려고 시도하고, 다른 일을 할 수 없다면 이상하게 보입니다. 재 시도로 돌아 가셨습니까? 어쩌면 약간 더 구체적인 것이 있다면 우리는 더 나은 방법을 제안 할 수 있습니다. – GManNickG

답변

2

밀짚 맨 답. 나는 이것이 유효한 대답이 아니라고 확신한다. 그러나 형식화 문제로 인해 주석에 넣을 수는 없습니다. 이 std::unique_lockstd::defer_lock 같은 C++ 11 비트를 사용하고

tile::generate_center() 
{ 
    tile& north = ...; 
    tile& east = ...; 
    tile& south = ...; 
    tile& west = ...; 
    std::unique_lock<mutex_type> l0(mutex(), std::defer_lock); 
    shared_lock<mutex_type> ln(north.mutex(), std::defer_lock); 
    shared_lock<mutex_type> le(east.mutex(), std::defer_lock); 
    shared_lock<mutex_type> ls(south.mutex(), std::defer_lock); 
    shared_lock<mutex_type> lw(west.mutex(), std::defer_lock); 
    std::lock(l0, ln, le, ls, lw); 
    // This is exclusively locked, neighbors are share locked 
    // ... 
} 

:

내가 이런 식으로 뭔가를 유혹 할 것이다 중심 타일을 생성합니다. 나는 당신이 부스트로부터이 기능을 얻을 수 있다고 믿는다 (긍정적이지는 않지만).

이 루틴은 기본적으로 중심을 고정시키고 이웃을 공유 잠금합니다. 그것은 모든 자물쇠를 얻을 수있을 때까지 차단합니다. 이웃 사람들이 같은 일을하지 못하게하지는 않습니다. 즉, std::lock을 사용하면 교착 상태가 발생하지 않습니다.

저는 실제로 이것이 당신이하려는 일을 실제로 처리하고 있는지 확실하지 않습니다. 하지만 아마도 그 대답에 이르게 도움이 될 것입니다 ...

+0

이것은 본질적으로 제가 그 기능을 가지고 있다고 생각하지 않기 때문에 std :: lock을 사용하지 않았다는 것을 제외하고는 결국 제가 끝난 것입니다. 이 접근법은 문제가 발생하거나 교착 상태에 빠지면 작동합니다. –

+0

'std :: lock'이 없다면'boost :: lock'을 시도하십시오. 두 개의 인접한 타일이 동시에 생성하려고 시도하면이 코드는 교착 상태가됩니다. –

관련 문제