[C++] 다양한 mutex, lock 중 뭘 써야하나.
그냥 락 거는 것 보다, 다음 API들을 사용하는게 좋다.
스코프를 벗어나면 자동으로 해제되는 lock을 걸기 위해서는 (since C++ 17 || boost)
```cpp
#include <mutex>
std::mutex mutex1;
std::mutex mutex2;
std::scoped_lock lock(mutex1, mutex2);
// lock.unlock();
```
이는 ``cpp std::lock_guard``에 여러 mutex들을 한번에 lock할 수 있는 기능을 추가한 완전한 상위 호환 API다.
mutex 하나 넘길 때도 퍼포먼스 걱정 안해도 된다고 함.
다양한 기능을 지원하는 unique_lock
근데 약간의 성능 패널티가 있다고 함.
충돌이 거의 없는 경우 lock을 거는 오버헤드가 적은 spinlock(atomic_flag)을 쓰자.
lock을 acquire하고 release하는건 syscall을 부르는 꽤 비싼 연산이다.
spinlock은 변수 하나의 0, 1을 체크해서 자원이 점유되고 있는지를 체크하는 lock이다.
자원이 점유 중이면, 릴리즈될 때 까지 while돌면서 계속 체크한다.
따라서 충돌이 발생하지 않는 경우 CPU를 많이 소모할 수 있지만, 충돌이 드물게 발생하는 경우라면 spinlock을 사용하는게 속도에 도움이 될 수 있다.
`` std::atomic_flag``로 간단히 구현할 수 있다.
https://en.cppreference.com/w/cpp/atomic/atomic_flag
* std::atomic_flag와 std::atomic<bool>의 차이?
``cpp atomic_flag.test_and_set()``은 변수 test-and-set을 한 과정의 atomic operation으로 처리하기 때문에 spinlock을 구현하려면 atomic_flag를 사용하는게 좋다.
``cpp atomic<bool>``은 if 체크면 체크만, 할당이면 할당만 원자적 연산을 보장해준다. 체크하면서 동시에 할당하는 것도 메서드로 지원하는 것 같기는 한데, 뭔가 spinlock으로 쓰라고 있는 건 아닌 듯.
그렇다고 ``cpp atomic<bool>``이 쓸모 없는거냐 하면 그 것도 아닌게, 스레드 내부의 running을 나타내는 변수 등에 쓰기에 적합하다.
'Languages & Frameworks > C C++' 카테고리의 다른 글
[C++] operator overloading (0) | 2019.01.22 |
---|---|
[C++] 구조체와 클래스의 차이 ( struct / class ) (0) | 2019.01.22 |
[C++] 생성자에서 throw하면(exception) 객체가 없어질까? / thread는 start() 함수로? (0) | 2018.09.12 |
[C++] thread는 context가 필요하다. (0) | 2018.09.11 |
[C++] lambda (bind 보다는 lambda를 쓰자) (0) | 2018.09.03 |