2011-09-11 2 views
7

누군가 boost :: upgrade_lock에 대한 올바른 사용법을 설명해 줄 수 있습니까? 교착 상태boost :: shared_lock을 exclusive lock으로 업그레이드

//Global 
typedef boost::shared_mutex Mutex; 
typedef boost::shared_lock<Mutex> ReadLock; 
typedef boost::upgrade_lock<Mutex> UpgradeLock; 
typedef boost::upgrade_to_unique_lock<Mutex> WriteLock; 
Mutex sharedMutex; 


//Multi threaded reader and writer 
{ 
    ReadLock read(sharedMutex); 

    for (int ii = 0; ii < vec.size(); ++ii) { 
     Element e = vec[ii]; 

     if (e.needsUpdating()) { 
      UpgradeLock upgrade(sharedMutex); 

      WriteLock write(upgrade) 

      //Do stuff 
     } 
    } 
} 

내가 업그레이드하기 전에 read.unlock()로 읽기 잠금을 해제 경우 교착하지 않습니다에서 다음 코드 결과. 그러나 이것이 필요하지 않아야하는 것 같습니다.

답변

9

클래스 (UpgradeLockable 개념을 구현)에서 단일 스레드는 공유 및 업그레이드 가능한 (또는 고유 한) 잠금을 모두 가져 오려고 시도하면 안됩니다. UpgradeLockable은 언제든지 N 개의 공유 잠금 (lock_shared 경유)과 1 개의 업그레이드 가능한 잠금 (lock_upgrade 경유)을 보유 할 수 있습니다. 업그레이드 가능한 잠금은 고유 잠금이되도록 요청할 수 있으며, 잠금은 독점적 소유자가 될 때까지 차단됩니다. 모든 공유 잠금이 해제되어야합니다. 공유 잠금을 고유 잠금으로 변환하거나 공유 잠금을 업그레이드 가능한 잠금으로 변환하는 것은 공유 잠금을 먼저 해제하지 않고 불가능합니다.

업그레이드 가능한 잠금은 강도를 높이기위한 특별한 권한이 있다는 것만 제외하면 독점적 인 것이 아닙니다 (다른 공유 잠금을 유지할 수 있음). 유감스럽게도 업그레이드 가능한 여러 스레드는 동시에 허용되지 않습니다.

동일한 스레드가 lock_sharedlock_upgrade을 사용하려고 시도하고 있는데 교착 상태가됩니다. 아래와 같이 다시 작성하면 교착 상태가되지 않지만 한 번에 1 개만 업그레이드 잠금을 유지하기 때문에 모든 독자에게 단일 경합 포인트가됩니다. 이 경우 다른 함수에 따라 shared_mutex의 복잡성이 필요하지 않을 수 있습니다. 그러나 다른 기능이 여전히 공유 잠금을 획득하는 경우, 아래 내용이 예상대로 수행됩니다.

//Multi threaded reader and writer 
{ 
    // Only 1 thread can pass this. Other shared locks are also valid 
    UpgradeLock read(sharedMutex); 

    for (int ii = 0; ii < vec.size(); ++ii) { 
     Element e = vec[ii]; 

     if (e.needsUpdating()) { 
      // Blocks here until all shareds are released 
      WriteLock write(upgrade) 

      //Do stuff 
     } 
    } 
} 
+0

아쉽게도 루프를 동시에 입력 할 수 있도록 여러 독자가 필요하므로 업그레이드 잠금을 사용할 수 없습니다. 설명 해줘서 고마워. –

관련 문제