Mutex & Atomic

Yoon Sunkue·2021년 10월 22일
1

노트

목록 보기
6/9

data-race 방지를 위한 도구, std::mutexstd::atomic 자세히 파고 들어가보자.
앞으론 std는 빼고 말하겠다.

이 글은 c++20, x86_cpu, MSVC, windows 기준으로 작성되었다.

  • mutex, atomic 은 구현체가 다르다.
  • mutex는 커널객체의 핸들이다.
  • atomic은 메소드만 변경된 래퍼클래스이다.

구현체
atomic 연산들은 하드웨어 구현이다.
mutex 의 작동은 운영체제가 구현한다.
이는 매 호출 마다 시스템콜을 해야한다는 말이다. 커널이 바쁘게 돌아간다는 얘기다.

mutex 구현, 윈도우의 방법은 아래와 같다. https://docs.microsoft.com/ko-kr/windows/win32/sync/mutex-objects
0. mutex는 커널객체의 핸들이다. createmutex로 생성한다. 생성스레드가 아닌 다른 스레드는 openmutex로 핸들을 얻는다.
1. 핸들이 있는 쓰레드가 wait 함수로 소유권을 요청한다. 다른 쓰레드가 소유중이면 커널객체가 releasemutex로 해제 될 때까지 요청쓰레드는 차단된다. 스케쥴링에서 제외된다.
2. wait 함수가 기대값으로 반환되면 커널객체를 소유하게 된 것이다. 소유권을 얻었다면 소유권을 포기 할 때 releasemutex 를 호출 해야 한다.

atomic 구현, 사실 atomic 표준은 원자성 만 보장한다. 이는 꼭 한 클럭에 실행된다는 얘기는 아니다. 자세히 알아보자. 별거 없고 그냥 메소드 래핑 클래스이다.

  • atomic_type :: atomic with built_in_type :: 하드웨어의 기능으로써 구현된다. 한개의 asm. 보통 떠올리는 바로 그 아토믹이다. :: wait_free 하다.
  • atomic<type> :: atomic with struct/class :: 뷜트인 타입이 아니더라도 std::atomic 으로 선언 가능하다. 사용자 정의 struct 를 이렇게 하는 경우가 있는데, 이 경우에는 global_mutex 가 암묵적으로 생성되여, lock, unlock 으로 원자성 보장을 한다. 이딴거 좋다고 쓰지 말자 blocking 이다.
  • atomic_memory_fence :: atomic fence :: 역시 어셈블리어 하나로 구현된다 하드웨어에서 구현되며, 특정한 계산 작업을 하지는 않는다. 다만 오더링을 강제한다. __asm mfence .
  • cpu 타입별 atomic 연산 매핑 :: https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html.

구현체의 차이로 인해, mutexatomic_flag는 개념은 같으나, 다르게 동작한다. 쓰레드 백오프 유무의 차이. 비지웨이팅에 대해 고려해서 무엇을 사용 할 지 정하자.
atomic<struct> 맹글어서 쓰면서 atomic이 나쁜경우도 있다고 하는 사람을 본 적이 있다. 바보다. 그러지 말자.

0개의 댓글