라벨이 fork인 게시물 표시

멀티 쓰레드 환경에서 fork는 조심해야 한다.

 리눅스나 유닉스 같은 POSIX 시스템에서는 fork 를 이용해서 자신과 똑같은 프로세스를 만들 수 있다. 이때 fork 를 호출한 프로세스를 부모 프로세스 라고 하고, 새로 생성된 프로세스를 자식 프로세스 라고 부르는데, 자식 프로세스는 부모 프로세스의 모든 메모리를 복사한다.   fork 는 그 뒤 exec 을 해서 다른 바이너리를 실행시키는 fork-exec 이 일반적인 사용법이다. 하지만 자식 프로세스 는 부모 프로세스 와 완전히 같은 메모리를 가지기 때문에, 스레드가 존재하지 않던 시절에는 exec 을 하지 않고 병렬 처리를 하기 위해서도 자주 사용되었다. 지금은 스레드를 사용하는 것이 더 사용하기 쉽고 가벼운 방식이기에 스레드를 병렬처리를 위해 스레드를 주로 사용하지만, 스레드보다 서로 간에 독립적이기 때문에 일을 분리하기 위해서 사용하기도 한다.  분명히 fork 는 없어서는 안 될 기능이지만 fork 에는 태생적 한계가 있다. 애초에 fork 는 스레드라는 개념이 존재하지 않던 시절에 만들어졌기 때문에 thread-safe 하지 않다. 따라서 멀티스레드 환경에서 사용하려면 조심해서 사용해야 한다.   fork 가 멀티스레드 환경에서 문제를 일으키는 이유는 fork 가 부모 프로세스 의 메모리를 전부 복사하지만, fork 를 호출한 스레드를 제외한 나머지 스레드들은 죽어버리기 때문이다. 따라서 fork 를 호출한 스레드 이외의 스레드에서 획득한 자원은 아무것도 해제되지 않는다. 메모리 릭도 충분히 문제지만, 이는 단순한 메모리 릭만을 의미하지 않는다.   fork 가 복사한 메모리에는 힙이나 스택 이외에 mutex 나 condition variable 들도 포함된다. 만약 mutex 나 condition variable 이 다른 스레드에서 사용된 채로 fork 된다면 해당 변수로 보호되는 critical section에는 다시는 진입할 수 없게 된다. 특히나 malloc 같은 thread-safe 한 함수는 대부분 내부적으로 글로벌한 m