rein’s world

프로그래머, 독서가, 게이머 그리고 블로거

멀티스레딩과 STL  

C++은 일반화 프로그래밍; generic programming 을 지원하는 언어다. 임의의 타입 T에 대한 클래스, 함수 등을 지정할 수 있고, 이를 컴파일 타임에 코드를 만들어내서† 사용할 수 있게 해준다. 사실 이런 부분이 가장 잘 반영되어 있는 것이 standard template libaray; STL 이고, 얼마 전에 확정된 tr1에 포함된 수많은 boost library 들이다.

이 중에서 STL과 멀티스레딩; multithreading 에 관해 한 가지 얘기를 해보려한다. 좀 된 얘기지만 (이미 졸업했지만) 과 IRC 채널에 STL의 스레드 안전성에 관한 뻘글 (댓글을 읽기가 괴로웠다), 또 다른 뻘글의 링크가 올라오기도 했었고, 오늘은 GPG 스터디 포럼에 STL 메모리 단편화 문제에 관한 질문이 올라 오면서 멀티스레딩 얘기가 잠깐 나오기도 했다 (중간의 답변글 중 하나가 너무 간단히 스레드 안전하지 않아 라고 말하고 있다).

위에서 링크한 STL 페이지에서도 말하고 있지만, STL에서 보장해주는 스레드 안전성; thread-safety 은 굉장히 단순하다. C++에서 int; integer 타입에서 기대할 수 있는만큼의 스레드 안전성을 보장한다‡.


간단히 설명하면 이렇다. 우선 STL 컨테이너 A, B가 있고 스레드 t1, t2, t3가 있다고 하자.

  • t1, t2, t3가 동시에 A를 읽는 것은 안전하다. 혹은 t1, t2는 A를 읽고 t3는 B를 읽는경우도 안전하다 - 한 객체를 동시에 읽는 것은 안전
  • t1이 A에 쓰고, t2는 B에 쓰는 것도 안전하다 - 같은 객체에 동시에 쓰는 것이 아니다
  • t1이 A에 쓰고, t2, t3는 B를 읽는 것도 안전하다 - 관계 없는 객체사이에선 무슨 짓을 해도 무방

…이런 식으로 int에 기대할 수 있는 수준으로는 기대해도 좋다. (그러니까 딱 상식적인 수준의 스레드 안전성을 보장한다)

왜 이 이상을 못하는지도 모두 꼭 한번씩 생각해보자. vector<some_type> v 라는 변수가 있다고 해보자. 만약 이런 코드를 실행시키면 어떨까? (미리 2 개 이상의 원소가 들어있는 상태였다고 하자)

Thread 1에서 if( v[0] == v[1] ) 어쩌구; 를 실행

Thread 2에서 if( v[1] == v[0] ) 저쩌구; 를 실행

만약 STL에서 int 같은 안정성보다 더 큰 안정성을 제공하면 v[0]와 v[1]의 lock을 동시에 잡아줘야 한다 - 그래야 비교하는 동안 값이 안변하니. 근데 T1에서는 0 1의 순서로 lock을 잡고, T2에서는 역순으로 잡는다. 뭔가 떠오르지 않는가? 예전에 설명했던 lock ordering 문제로 데드락; deadlock에 빠진다. 즉, STL에서 단순한 스레드 안전성 이상의 뭔가를 제공하려는 순간 두 가지 선택에 직면하게 된다.

  • 데드락의 위험을 사용자가 미리 알고 잘 대처하게 한다 - 라이브러리는 잘못 사용되기 힘들어야한다는 원칙에 위배
  • 더 복잡한 알고리즘을 써서 락 순서 문제를 내부적으로 해결한다 - 실제로 필요하지 않을 곳에도 불필요한 복잡성을 부여해서 효율성을 추구하는 C++의 목적을 방해

둘 다 문제가 있다. 그래서 C++의 STL은 아주 단순한 수준의 스레드 안전성을 보장해준다.

“STL은 스레드 안전성이 없다” 와 “STL은 이런 형태의 - 그러니까 int 같은 - 안전성을 제공한다” 라는 두 명제 사이의 차이는 엄청난 것이다. 무엇이 가능한지 잘 알고 프로그래밍하는 것이 좋겠다.

여담이지만 학부시절에 동기 중에 이정도도 모르는 사람이 있었는데 회사 와서는 아직 그런 사람을 찾지 못해서 무척 행복하다.

*

† 컴파일 시간에 타입에 따라 다른 기능을 갖게 할 수도 있기 때문에, 이런 기능을 사용해는 것을 컴파일 시간 다형성; compile time polymorphism 이라고 부르기도 한다.

‡ 그렇다고 volatile int 에 사용할 수 있는 atomic operation을 사용한 수준의 안전성을 기대하진 말자.

ps. 안전성을 자꾸 으로 쓰는 저주받은 손 때문에 글 쓰는 내내 괴로웠다(…)


 

By rein

September 19th, 2007 at 12:16 am

2 Responses to '멀티스레딩과 STL'

Subscribe to comments with RSS or TrackBack to '멀티스레딩과 STL'.

  1. 아하, 이런 내막이 있었군요. 그저 “민감한 작업만 안하면 된다. 민감한 작업을 하는 클래스를 컨테이너에 담을 거면 그 클래스 단에서 스레드 안정성 체크만 해주면 된다.” 정도로만 알고 있었는데 무적의 군주사마 덕분에 제 지식을 업데이트할 수 있었습니다(?)

    고어핀드

    19 Sep 07 at 3:07 pm

  2. 뭐 사실 따지고 보면 원론적인 얘기지. 일반적인 int 에 적용되는대로만 생각하면 된다랄까;

    rein

    19 Sep 07 at 3:35 pm

Leave a Reply