std :: unique_lock 또는 std :: lock_guard?
두 가지 사용 사례가 있습니다.
A. 두 스레드의 액세스를 대기열에 동기화하고 싶습니다.
B. 두 스레드의 액세스를 큐에 동기화하고 스레드 중 하나가 다른 스레드에 의해 큐에 저장 될 내용을 기다리는 조건 변수를 사용하려고합니다.
사용 사례 AI의 경우를 사용하는 코드 예를 참조하십시오 std::lock_guard<>
. 사용 사례 BI의 경우를 사용하는 코드 예를 참조하십시오 std::unique_lock<>
.
둘 중 어느 것과 어떤 유스 케이스에서 사용해야하는지의 차이점은 무엇입니까?
차이점은를 잠그고 잠금을 해제 할 수 있다는 것 std::unique_lock
입니다. std::lock_guard
건설시 한 번만 잠기고 파괴시 잠금이 해제됩니다.
따라서 유스 케이스 B의 경우 std::unique_lock
조건 변수에 반드시 a가 필요 합니다. A의 경우 가드를 다시 잠글 지 여부에 따라 다릅니다.
std::unique_lock
뮤텍스를 즉시 잠그지 않고 RAII 래퍼를 빌드하도록 구성 할 수있는 다른 기능이 있습니다 ( 여기 참조 ).
std::lock_guard
또한 편리한 RAII 래퍼를 제공하지만 여러 뮤텍스를 안전하게 잠글 수는 없습니다. 제한된 범위에 대한 랩퍼가 필요할 때 사용할 수 있습니다 (예 : 멤버 함수).
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard<mutex_type> lock(this->my_mutex);
/*
block of code which needs mutual exclusion (e.g. open the same
file in multiple threads).
*/
//mutex is automatically released when lock goes out of scope
};
기본적으로 chmike으로 질문을 명확히하기 std::lock_guard
와 std::unique_lock
동일합니다. 따라서 위의 경우로 대체 할 수 std::lock_guard
있습니다 std::unique_lock
. 그러나 std::unique_lock
약간 더 많은 오버 헤드가있을 수 있습니다.
요즘에는 std::scoped_lock
대신에 사용해야 합니다 std::lock_guard
.
lock_guard
그리고 unique_lock
거의 같은 것입니다; lock_guard
인터페이스가 제한된 제한된 버전입니다.
A는 lock_guard
항상 건축에서 파괴까지 잠금을 유지합니다. A unique_lock
는 즉시 잠그지 않고 생성 할 수 있으며, 존재하는 어느 시점에서나 잠금 해제 할 수 있으며, 잠금 소유권을 한 인스턴스에서 다른 인스턴스로 이전 할 수 있습니다.
따라서 lock_guard
의 기능이 필요하지 않으면 항상을 사용 하십시오 unique_lock
. A가 condition_variable
필요합니다 unique_lock
.
를 파괴하지 않고 사이 lock_guard
에 수동으로 unlock
뮤텍스를 할 수 있어야하지 않는 한 사용하십시오 lock
.
특히 condition_variable
에 호출 할 때 절전 모드로 전환 할 때 뮤텍스를 잠금 해제합니다 wait
. 이것이 lock_guard
여기에서 충분하지 않은 이유 입니다.
사이의 공통된 것들이있다 lock_guard
및 unique_lock
특정 차이.
그러나 질문의 맥락에서 컴파일러는 lock_guard
조건 변수와의 조합을 사용할 수 없습니다 . 스레드 호출이 조건 변수를 기다릴 때 뮤텍스가 자동으로 잠금 해제되고 다른 스레드 / 스레드가 통지하고 현재 스레드를 호출되면 (대기에서 나옴) 잠금이 다시 획득됩니다.
이 현상은의 원칙에 위배 lock_guard
됩니다. lock_guard
한 번만 구성하고 한 번만 파괴 할 수 있습니다.
따라서, lock_guard
조건 변수와 함께 사용되지 않을 수 있지만,이 unique_lock
(때문 될 수 unique_lock
잠겨 수회 해제 할 수있다).
다른 사람들이 언급했듯이 std :: unique_lock은 뮤텍스의 잠금 상태를 추적하므로 잠금 생성 후까지 잠금을 연기하고 잠금이 파괴되기 전에 잠금을 해제 할 수 있습니다. std :: lock_guard는 이것을 허용하지 않습니다.
std :: condition_variable 대기 함수가 고유 한 잠금뿐만 아니라 lock_guard를 가져 가지 않아야 할 이유가 없습니다. 대기가 종료 될 때마다 (어떤 이유로 든) 뮤텍스가 자동으로 다시 획득되어 의미 위반이 발생하지 않기 때문입니다. 그러나 표준에 따르면 조건 변수와 함께 std :: lock_guard를 사용하려면 std :: condition_variable 대신 std :: condition_variable_any를 사용해야합니다.
편집 : 삭제 "pthreads 인터페이스 std :: condition_variable과 std :: condition_variable_any는 동일해야합니다." gcc의 구현을 살펴보면 다음과 같습니다.
- std :: condition_variable :: wait (std :: unique_lock &)은 unique_lock이 보유한 뮤텍스와 관련하여 기본 pthread 조건 변수에서 pthread_cond_wait ()를 호출합니다 (따라서 lock_guard에 대해 동일하게 수행 할 수는 있지만 표준이 아니기 때문에) 그것을 제공하지 않습니다)
- std :: condition_variable_any는 뮤텍스 잠금이 아닌 객체를 포함하여 모든 잠금 가능 객체에서 작동 할 수 있습니다 (따라서 프로세스 간 세마포어로도 작동 할 수 있음)
참고 URL : https://stackoverflow.com/questions/20516773/stdunique-lockstdmutex-or-stdlock-guardstdmutex
'Programing' 카테고리의 다른 글
iPhone 앱 서명 :이 프로파일과 일치하는 유효한 서명 ID를 키 체인에서 찾을 수 없습니다 (0) | 2020.03.10 |
---|---|
SQL Server에서 이중을 나타내는 것은 무엇입니까? (0) | 2020.03.10 |
파이썬에서 문자열을 연결하는 가장 좋은 방법은 무엇입니까? (0) | 2020.03.10 |
pip를 사용하여 개인 GitHub 저장소에서 패키지를 설치할 수 있습니까? (0) | 2020.03.10 |
유형이 하위 유형인지 또는 객체 유형인지 어떻게 확인합니까? (0) | 2020.03.10 |