C ++ 11 : std :: condition_variable이 std :: unique_lock을 사용하는 이유는 무엇입니까?
을 (를) std::unique_lock
사용할 때 의 역할에 대해 약간 혼란 스럽 습니다 std::condition_variable
. 내가 문서를 이해하는 한 , std::unique_lock
기본적으로 두 개의 자물쇠 사이의 상태 를 바꿀 수있는 확장 된 자물쇠 가드입니다 .
나는 지금 pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
까지이 목적으로 사용되는 (STL이 posix에서 사용하는 것입니다). 잠금이 아닌 뮤텍스가 필요합니다.
여기서 차이점은 무엇입니까? 이것이 최적화 를 std::condition_variable
다룬다 는 사실 std::unique_lock
입니까? 정확히 얼마나 빠릅니까?
그 이유가 없나요?
나는 그가 작성한 이유를 제공했다고 믿기 때문에 cmeerw의 답변을 찬성했습니다. 보겠습니다. 하자가위원회로 결정했다 척 condition_variable
A의 대기 mutex
. 다음은 해당 디자인을 사용하는 코드입니다.
void foo()
{
mut.lock();
// mut locked by this thread here
while (not_ready)
cv.wait(mut);
// mut locked by this thread here
mut.unlock();
}
하나의 방법 이것은 정확히 안 을 사용합니다 condition_variable
. 다음으로 새로운 지역에서 :
// mut locked by this thread here
예외 안전 문제가 심각한 문제입니다. 예외가 발생 하면 (또는 여기서) 예외가 발생 cv.wait
하면 잠금을 해제하기 위해 예외를 어딘가에 배치되지 않는 한 뮤텍스의 잠긴 상태가 있습니다. 그러나 그것은 프로그래머에게 요구하는 코드에 불고기합니다.
프로그래머가 예외 안전 코드를 작성하는 방법을 알고 unique_lock
있고 달성하기 위해 사용하는 방법을 알고 가정 해 보겠습니다 . 이제 코드는 다음과 달라집니다.
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(*lk.mutex());
// mut locked by this thread here
}
이것은 훨씬 낫지 만 여전히 좋은 상황은 아닙니다. condition_variable
인터페이스는 프로그래머가 작업에 물건을 가지고 자신의 방식으로 외출하고 있습니다. lk
실수로 뮤텍스를 참조하지 않는 경우 널 포인터 역 참조가 보관 수 있습니다 . 그리고이 condition_variable::wait
행사가에 대한 잠금을 소유하고 있는지 확인 방법이 없습니다 mut
.
오, 기억하십시오. 가 프로그래머 unique_lock
뮤텍스를 노출하기 위해 잘못된 멤버 함수를 선택할 수있는 위험도 있습니다 . *lk.release()
여기서는 재앙이 될 것입니다.
이제 다음을 사용하는 실제 condition_variable
API로 코드를 작성하는 방법을 보겠습니다 unique_lock<mutex>
.
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(lk);
// mut locked by this thread here
}
- 이 코드는 가능한 한 간단합니다.
- 예외적으로 안전합니다.
- 이
wait
함수lk.owns_lock()
는 예외가있는 경우 확인 하고 예외를 throw 할 수 있습니다false
.
.NET의 API 설계를 주도한 이유는 다음과 가변적 condition_variable
입니다.
또한 당신이 말하는 방식 이기 때문에 condition_variable::wait
를 사용하지 않습니다 . 그러나를 호출 하면 암시 적으로 뮤텍스에 대한 잠금을 해제합니다. 따라서 해당 작업은 사용 사례 / 문과 일치하지 않습니다 .lock_guard<mutex>
lock_guard<mutex>
lock_guard<mutex>
condition_variable::wait
lock_guard
unique_lock
어쨌든 우리는 함수에서 잠금을 반환하고 컨테이너에 예외, 예외 방식으로 범위가 지정되지 않은 패턴으로 뮤텍스를 잠 그거나 잠금 해제 할 unique_lock
수 있습니다 condition_variable::wait
..
최신 정보
bamboon은 아래의 주석에서 내가 대조적으로 제안했습니다 condition_variable_any
.
질문 :condition_variable::wait
모든 Lockable
유형을 전달할 수 있도록 템플릿 이 지정되지 않은 이유는 무엇 입니까?
대답 :
정말 멋진 기능입니다. 예를 들어, 이 문서shared_lock
는 조건 변수에 대해 공유 모드에서 (rwlock) 을 기다리는 코드를 보여줍니다 (posix 세계에서는 들어 보지 못했지만 그럼에도 불구하고 매우 유용함). 그러나 기능은 더 비쌉니다.
그래서위원회는이 기능을 가진 새로운 유형을 도입했습니다.
`condition_variable_any`
이 condition_variable
어댑터를 사용하면 모든 잠금 유형을 기다릴 수 있습니다 . 이 멤버가있는 경우 lock()
와 unlock()
, 당신은 갈 수 있습니다. 의 적절한 구현 condition_variable_any
에는 condition_variable
데이터 멤버와 데이터 멤버 가 필요합니다 shared_ptr<mutex>
.
이 새로운 기능이 기본보다 더 많은 비용이 있기 때문에 condition_variable::wait
, 그리고 있기 때문에이 condition_variable
같은 낮은 수준의 도구이며,이 매우 유용하지만 더 비싼 기능이 있으므로 별도의 클래스에 넣고 그것을 위해 당신 만 지불 당신이 그것을 사용하는 경우 그.
기본적으로 API를 가능한 한 안전하게 만드는 것은 기본적으로 API 설계 결정입니다 (추가 오버 헤드는 무시할 수있는 것으로 간주 됨). API unique_lock
의 원시 mutex
사용자 대신 a를 전달하도록 요구함으로써 (예외가있는 경우) 올바른 코드를 작성하도록 안내합니다.
최근 몇 년 동안 C ++ 언어의 초점은 기본적으로 안전하게 만드는쪽으로 바뀌 었습니다 (그러나 사용자가 원할 경우 충분히 열심히 시도 할 수 있도록 허용).
참고 URL : https://stackoverflow.com/questions/13099660/c11-why-does-stdcondition-variable-use-stdunique-lock
'ProgramingTip' 카테고리의 다른 글
Postgresql에서 이름으로 제약 조건 삭제 (0) | 2020.11.01 |
---|---|
Internet Explorer 10 Windows 8 텍스트 입력 및 암호 작업 아이콘 제거 (0) | 2020.11.01 |
크롬 확장을 사용하여로드 된 페이지의 HTML 수정 (0) | 2020.11.01 |
node.js를 설치 / 설치하는 방법 (cxx 컴파일러를 구성 할 수 없습니다!) (Ubuntu). (0) | 2020.10.31 |
NSMutablearray를 졸업을 무대로 이동 (0) | 2020.10.31 |