2012년 2월 12일 일요일

reentrant (재진입성) 함수와 쓰레드안전(MultiThread-safe)

질문1. reentrant와 MT-safety의 정확한 차이는 무엇인가?



eentrant와 MT-safety의 가장 큰 차이는 코드가 어떠한 경우에도 병렬 실행을 보장할 수 있느냐의 여부입니다.
Reentrant function : "A function whose effect, when called by two or more threads, is guaranteed to be as if the threads each executed the function one after another in an undefined order, even if the actual execution is interleaved." - Single UNIX Specification version 3
SUSv3 표준안(http://pubs.opengroup.org/onlinepubs/009695399/)에 의하면 "reentrant 함수는 둘 이상의 쓰레드에 의해서 호출될 경우에 순서에 구애받지 않고, 서로 동일한 코드가 겹쳐서 실행되어도 작동이 보장되어야 함"을 말하고 있습니다.
이를 다른 말로 풀어서 설명하면 reentrant function은 재귀호출을 포함한 병렬 실행을 완벽히 보장하는 코드를 의미합니다. 즉 쓰레드나 시그널 핸들러에서 마음껏 사용해도 괜찮으며, 심지어 재귀 호출코드에 들어 넣어도 안전하다는 뜻입니다.
그러면 비교대상인 Thread-safe는 어떻게 쓰여 있을까요? 이를 SUSv3 (POSIX.1-2001)에서 찾아보면 아래와 같이 적어두고 있습니다. - 참고: 표준안에서는 Thread-safe한 함수를 TSF(Thread-Safe-Function)이라고도 부릅니다.
Thread-safe (Thread-safety) : "A function that may be safely invoked concurrently by multiple threads. Each function defined in the System Interfaces volume of IEEE Std 1003.1-2001 is thread-safe unless explicitly stated otherwise. Examples are any "pure" function, a function which holds a mutex locked while it is accessing static storage, or objects shared among threads."
Thread-safe도 복수의 쓰레드에서 호출 될 수 있고 병렬로 실행 될 수도 있습니다. 다만 완벽한 병렬을 보장하지는 않고 정적 공간(static storage = 전역변수, BSS 메모리 등)이나 공유 객체(heap과 같은 메모리 객체)가 있다면 MUTEX와 같은 매커니즘으로 보호해야만 합니다. 그리고 뮤텍스 락으로 보호되는 서브 루틴은 직렬로 실행됩니다.

따라서 only 쓰레드 안전을 만족하는 코드라면, 정적공간이나 공유 객체를 사용하면 진입순서에 따라 실행 결과가 달라질 수 있습니다.

그렇다면 모든 reentrant 함수는 thread-safe를 만족한다고 말할 수 있을 겁니다. 하지만 그 역은 성립하지 않습니다. 그리고 눈치가 빠른 분들은 reentrant 함수는 static storage를 사용하지 않아야 한다는 것을 알 수 있을 것입니다.
이제 여러분이 어떤 함수를 만들었는데 병렬 실행이 가능하고 static storage를 사용하지 않는 구조라면 reentrant 함수라고 말할 수 있고, 병렬 실행이 가능하지만 서브 루틴에서 static storage나 shared object를 사용하며 lock으로 보호해두었다면 Thread-safe만 만족하는 함수라고 말할 수 있다는 것입니다.


긴 글이 도움이 되기를 바라면서... 이 글은 저작자와 출처만 표시하신다면 마음대로 복사, 발췌하셔도 괜찮습니다. 
(굳이 몰라서 출처 표시 안해도 고소하지 않으니 안심하시길...^^)


다만 제 글을 퍼가신다면 꼭 다른 사람도 쉽게 발췌하거나 복사할 수 있도록 해주시기 바랍니다. 
오른쪽 마우스 금지스크랩 금지 혹은 드래그 금지를 해두는 것은 좋지 않다고 생각합니다. 
다른 사람에게 지식을 나눠준다고 해서 본인의 지식이 줄어들지 않으니, 남에게 지식을 주는 것에 인색하지 않았으면 좋겠군요.


댓글 없음:

댓글 쓰기