C ++ 17은이라는 새로운 잠금 클래스를 도입했습니다 std::scoped_lock
.
문서에서 판단하면 기존 std::lock_guard
클래스 와 비슷하게 보입니다 .
차이점은 무엇이며 언제 사용해야합니까?
C ++ 17은이라는 새로운 잠금 클래스를 도입했습니다 std::scoped_lock
.
문서에서 판단하면 기존 std::lock_guard
클래스 와 비슷하게 보입니다 .
차이점은 무엇이며 언제 사용해야합니까?
답변:
이 scoped_lock
의 엄격 우수한 버전 lock_guard
즉 (같은 교착 상태 회피 알고리즘 등을 이용하여 한번에 뮤텍스 모든 임의의 수를 잠근다 std::lock
). 새 코드에서는을 사용해야합니다 scoped_lock
.
lock_guard
여전히 존재 하는 유일한 이유 는 호환성 때문입니다. 현재 코드에서 사용되기 때문에 삭제할 수 없습니다. 또한 정의를 변경하는 것은 바람직하지 않은 것으로 판명되었습니다. 단항에서 가변으로 변경하는 것도 관찰 가능하고 따라서 변경, 그러나 약간의 기술적 이유 때문에 변경되기 때문입니다.
lock_guard
. 그러나 가드 클래스를 사용하기가 더 쉽습니다.
하나의 중요한 차이점은 std::scoped_lock
variadic 생성자가 둘 이상의 뮤텍스를 사용 한다는 것입니다. 이렇게하면 여러 뮤텍스를 교착 상태에서 잠그는 것처럼 피할 수 std::lock
있습니다.
{
// safely locked as if using std::lock
std::scoped_lock<std::mutex, std::mutex> lock(mutex1, mutex2);
}
이전에는 이 답변에std::lock
설명 된대로 여러 뮤텍스를 안전하게 고정하기 위해 약간의 춤을 추어 야했습니다 .
스코프 잠금 기능을 추가하면보다 쉽게 사용할 수 있으며 관련 오류를 피할 수 있습니다. std::lock_guard
더 이상 사용되지 않는 것으로 간주 할 수 있습니다 . 의 단일 인수 사례 std::scoped_lock
는 전문화로 구현할 수 있으므로 가능한 성능 문제에 대해 걱정할 필요가 없습니다.
GCC 7은 이미 여기에서std::scoped_lock
볼 수있는 지원을 제공 합니다 .
자세한 내용은 표준 용지를 참조하십시오
scoped_lock lk; // locks all mutexes in scope
. LGTM.
scoped_lock lk;
의 새로운 속기입니다 scoped_lock<> lk;
. 가 없습니다 더 뮤텍스는. 네 말이 맞아 ;-)
답변이 늦었고 대부분 다음에 대한 응답으로 :
std::lock_guard
더 이상 사용되지 않는 것으로 간주 할 수 있습니다 .
하나의 뮤텍스를 정확히 잠글 필요가있는 일반적인 경우 std::lock_guard
보다 사용하기에 조금 더 안전한 API가 있습니다 scoped_lock
.
예를 들면 다음과 같습니다.
{
std::scoped_lock lock; // protect this block
...
}
위의 스 니펫은 컴파일 된 다음 전혀 아무것도하지 않기 때문에 우연히 런타임 오류 일 가능성이 큽니다. 코더는 아마도 다음을 의미했습니다.
{
std::scoped_lock lock{mut}; // protect this block
...
}
이제 잠금 / 잠금 해제 mut
됩니다.
lock_guard
위의 두 예에서 대신 사용 된 경우 첫 번째 예는 런타임 오류 대신 컴파일 타임 오류이며 두 번째 예는를 사용하는 버전과 동일한 기능을 갖습니다 scoped_lock
.
그래서 내 조언은 작업에 가장 간단한 도구를 사용하는 것입니다.
lock_guard
전체 범위에 대해 정확히 1 개의 뮤텍스를 잠글 필요가있는 경우.
scoped_lock
정확히 1이 아닌 여러 뮤텍스를 잠 가야하는 경우
unique_lock
블록 범위 내에서 잠금을 해제해야하는 경우 ( condition_variable
).
이 조언 은 0 개의 뮤텍스를 허용하지 않도록 재 설계되어야 함을 의미 하지 않습니다scoped_lock
. scoped_lock
비어있을 수있는 가변 템플릿 매개 변수 팩을 수용하는 것이 바람직한 유효한 사용 사례 가 있습니다. 그리고 비어있는 경우는해야 하지 아무것도 잠급니다.
그리고 이것이 lock_guard
더 이상 사용되지 않는 이유 입니다. scoped_lock
과 unique_lock
의 기능의 상위 집합이 될 수 lock_guard
있지만, 사실은 양날의 칼이다. 때로는 유형 이 수행하지 않는 것이 중요합니다 (이 경우 기본 구성).
다음은 C ++ 동시성 작업 의 샘플과 인용문입니다 .
friend void swap(X& lhs, X& rhs)
{
if (&lhs == & rhs)
return;
std::lock(lhs.m, rhs.m);
std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock);
std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock);
swap(lhs.some_detail, rhs.some_detail);
}
vs.
friend void swap(X& lhs, X& rhs)
{
if (&lhs == &rhs)
return;
std::scoped_lock guard(lhs.m, rhs.m);
swap(lhs.some_detail, rhs.some_detail);
}
존재
std::scoped_lock
한다는 것은std::lock
c ++ 17 이전에 사용했던 대부분의 경우std::scoped_lock
를 실수로 사용할 가능성이 적은을 사용하여 작성할 수 있다는 것을 의미합니다.