Win32 멀티스레드 프로그래밍에서 아쉬운 것

Windows Server 2003까지 아쉬운 거라고 해야 맞겠지만 아직 2008이 내 손에 넘어온 것은 아니므로[…] 일단 토픽은 저렇게;

Win32 API가 pthread 라이브러리에 비해서 가장 부족하다고 – 그리고 아쉽게 생각하는게 – 느껴지는게, conditional variable의 존재다. Event 라는 객체를 제공해주긴 하는데 뭔가 2% 부족하달까;

일단 Event는 두 가지 형태로 생성이 될 수 있다 – manual reset event (signaled -> non-signaled 전환이 수동) 와 auto reset event 2가지.

그리고 signaled state로 변환시키는 함수가 2가지 존재한다.

  • SetEvent() : Signaled로 전환. Manual reset event는 ResetEvent()할 때까지 계속 signaled. Auto-reset이면 1개만 깨어나고 나머지는 대기 상태 유지
  • PulseEvent() : Signaled로 갔다가 바로 non-signaled로 전환. Manual reset event이면 대기 중이던 스레드가 전부 깨어나고, auto reset이면 한 개만 깨어난다

…이게 일반적으로 알려진 설명이다.

일단 내가 생각하는 가장 짜증나는 점은, 하나의 API가 하나의 의미를 갖지 않는다는 것 – pthread conditional variable은 생성/제거/대기/1개만 깨우기/죄다 깨우기 이런 식으로 각 함수가 분리되어있음.

그리고 더 무서운 사실은, Win32 API가 저 의미대로도 동작하지 않을 때가 있다는 것이다.

예를 들어 auto reset event라고 해보자.

  1. 스레드 T1이 이벤트에 대기 시작.
  2. T1이 asynchronous procedure call; APC 로 잠시 이벤트 대기 큐에서 벗어남
  3. APC가 실행되는 동안 PulseEvent()가 대기 중이던 이벤트에 호출됨- 기다리는 스레드가 없으니 깨우지 않고 통과
  4. T1이 APC를 끝내고 다시 대기 – 이벤트를 놓쳤음 ㄳㄳ(?)

Manual reset event에서 PulseEvent를 하는 경우에도 비슷한 시나리오가 하나 나온다.

물론 APC가 그렇게 자주 사용되는 방식은 아니고 – 적어도 지금은 그렇다고 생각된다 – Wait-Ex류의 함수들을 쓰지 않는 이상 APC가 호출되지도 않는다. 그렇지만 유저 레벨 동기화 객체도 아니고 커널 객첸데 이러는 건 조금[………]

그런 의미에서 server 2008에서는 conditional variable이 등장한다. 인터페이스도 pthread와 거의 같다 – 다만 pthread에서 이벤트를 흘리지 않기 위한[…] 도구로 pthread_mutex_t 만 쓰지만 Win32에선 critical section이나 SlimRWLock (역시 서버 2008에서 추가)를 쓸 수 있다.
그러니 제발 빨리 발매 쫌[…]

Author: rein

나는 ...

4 thoughts on “Win32 멀티스레드 프로그래밍에서 아쉬운 것”

  1. 오홋 댓글 넘 많이 달아 죄송해요. 역시 pthread Win32 포팅을 보면 뭐 충분히 Win32 sync primitive로 condition variable이 가능하지요. 뭐 그런게 없어도 최악의 경우 x86 asm 가지고도 다 만들 수는 있으니깐요. 말씀대로 NT 6.0 (비스타, 윈서버2008) 에 추가된 여러 sync primitive는 꽤 매력적입니다.

  2. 가능하긴한데 딱히 필요한…적어도 지금 시점엔…건 아니라서 일단 그냥 있는걸로만 쓰고 있습니다. APC를 안쓰고있기도해서 /먼산

    비스타랑 Windows Server 2008의 동기화 객체들은 무척 매력적이죠…

    ps. 댓글 많이 달아준다고 — (스팸만 아니면) — 싫어할 블로거는 별로 없겠죠 ~_~

Leave a Reply