갑자기 쓰레드에 관련된 이야기가 나와서, 어리 둥절했었다. 이번 항목은 쓰레드간의 안전한 공유를 위한 코딩의 시기와 방식을 어떻게 결정하는지에 대해서 이야기 한다.
이번 주제에 대해서 이야기 하기전에 비유가 되는 한가지 이야기를 생각해 봤다.
어느 마을에 의자를 아주 잘 만드는 사람이 있었다. 그 사람은 구현자이다. 구현자는 의자를 만들때 아주 깔끔하고 튼튼하게 만들기로 유명하다. 구현자가 만든 의자는 호출자에 의해 운반되어 시장에 팔린다. 사람들은 호출자가 운반한 의자가 구현자가 만든 것임을 알고 있기에 의심치 않고 구매를 한다.
어느날 호출자는 다른 시장에도 의자를 팔기 위해서 구현자에게 의자를 더 만들어 달라고 요청을 했고, 구현자는 사람들을 고용하여 의자를 더 만들었다. 다음날 호출자는 일상대로 구현자의 의자를 운반했고, 다른 시장에도 판매한다.
의자는 사람들에게 전달되어, 사용 되었다. 그런데 이 의자는 쉽게 부셔지는 것이다.사람들은 다시는 호출자의 의자는 사지 않겠다고 다짐을 한다. 다음날, 호출자는 다시 시장에 와서 의자를 판매 하려고 하지만, 아무도 호출자가 가져온 의자를 살려고 하지 않는다.
호출자와 구현자는 이 사태를 파악하고 대처하여, 다시 의자를 판매 했다. 의자는 다시 불티나게 팔리기 시작해 호출자와 구현자는 부자가 되었다.
의자가 쉽게 부셔진 이유는 무엇일까?
의자를 A/S 하던 구현자는 "의자의 품질이 매우 안좋다는 점"을 알게 되었다
구현자는 어떻게 대처 했을까?
구현자는 고용했던 사람들에게 의자를 잘 만드는 방법을 알려 준 뒤에 감수를 하기 시작했고, 감수에 통과한 의자만이 완성된 의자 창고에 갔다 놨다. 호출자는 이 완성된 의자 창고에서만 의자를 가져와 시장에 내다판 것이다.
이 일화는 "안전한 판매"를 위한 "의자의 판매 시기와 방식"을 결정하는 이야기 이다. 이 일화에서의 판매를 공유로 바꾸어 보면, 쓰레드에서 데이터의 안전한 공유에 대해서 감이 오게 될 것이다.
데이터의 안전한 공유를 위한 시기를 어떻게 결정하는가?
위 일화에서는 "다른 시장"으로 인해 작업량이 늘어나, 의자를 만드는 사람들을 고용(쓰레드)했던 시기, 즉, 다른 쓰레드에서 사용 되어 지거나, 만들어진 것을 공유하려 할때가 바로 "데이터의 안전한 공유를 위한 시기"라고 본다.
데이터의 안전한 공유를 위한 방식은 어떻게 결정하는가?
이 때의 요령으로는 타켓이 되는 플랫폼의 문서를 일단 보고, 플랫폼의 기본 기능들(쓰레드에 관련된)을 추상체에 포함시키고, 사용하고 있는 타입이 멀티쓰레드 프로그램에서 안전한지 확인하고 결정한다.
일반적으로 어떤 방법을 이용하는가?
플랫폼에서 지원하는 락( 윈도우는 Critical Section, 리눅스는 mutex )을 만들고 작업중일 땐 방해 없이 집중하기 위해서 락을 잠가놓고 일이 끝나면 락을 풀어 버리는 방법을 이용한다.
다른 방법으로는 자물쇠 없이도 작업할 수 있는 환경을 든다. 즉, 디자인 적으로 서로 독립적으로 만들어 버리는 것이다.
락은 어떻게 거는게 좋을까?
제일 중요한것이 데드락 없이 만들어야 하며(클래스의 생성자와 소멸자를 이용하는 방법이 제일 편하다), 호출자 또는 구현자가 그 락을 사용하게 좋을지 생각해야 한다.
구현자가 락을 걸면 어떤 장단점이 있는가?
우선 호출자는 락에 대해서 신경을 쓰지 않아도 되어서 편하지만, 대부분의 호출자에 대해서 적절한 선택인지 확인해야 하고, 내부 데이터가 잠금의 밖으로 나가는 경우 큰 문제가 생길 수 있다.
호출자가 락을 걸면 어떤 장단점이 있는가?
일련이 작업들이 쓰레드에서 어떻게(데이터 공유가 어떻게) 작동하는지 확인해야 하지만, 구현자쪽에선 신경쓰지 않아도 되는 장점이 있다.
총평
쓰레드의 사용은 많은 경험과 정보를 필요로 한다. 책의 내용은 읽으면서 넘어가는 수준이지만, 더 깊게 알고 싶다면, 각 플랫폼의 쓰레드 환경과 지원 API 들, 그리고, 디자인적인 구조에 대해서 더 찾아 봐야 할 것이다.
최근댓글