그럼, 아직 말하지 않은 thread는 무엇인가?
Thread 란 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들을 대부분 공유하면서 실행되는 객체를 말한다. 근래의 대부분의 시스템은 multi thread program 이 기본이며, 이는 하나의 프로세스 내에 여러 개의 thread 들이 실행 가능하다는 의미이다.
기본적으로 하나의 process가 생성되면 하나의 thread가 같이 생성된다. 이를 mian thread라고 부르며, thread를 추가로 생성하지 않는 한 모든 프로그램 코드는 메인 thread에서 실행된다. 이 process 는 fork를 통해 child process를 가질 수 있으며 이를 multi thread 라고 한다. 리눅스에서 process 와 thread 를 구분을 하지 않는다. 둘 다 동일하게 task_struct 로 표현되며, process 와 thread 는 리눅스에서 둘 간이 구별되는 조금 다른 처리를 받을 뿐이다.
프로세스가 생성되고 그 프로세스 내의 쓰레드들은 프로세스 내의 자원을 공유하면서, 각 쓰레드의 프로그램을 실행한다. 리눅스 코드 영역과 라이브러리를 프로세스 내부로는 공유하며, 각 쓰레드들은 실행 위치를 나타내는 PC(Program Counter), register 정보들을 포함한 스택, 변수 할당으로 채워지는 데이터 세그먼트 각각 저장관리한다. 각 쓰레드들이 독립적으로 실행한다는 점을 생각하면, 실행 정보와 관련한 것들은 각각 정장되어 있어야 한다는 점은 너무 당연한 것이다.
아래 프로세스와 쓰레드 간의 자원 공유 상태를 그림으로 표현해봤다.
쓰레드는 프로세스 내에서 코드, 전역 변수, 파일등을 공유한다.(리눅스의 clone 함수로 스레드가 생성될때, flag에 의해 공유가 얼마정도 허용되는지를 정한다.) 이는 프로그램을 구현할 때, 매우 중요한 요소이다. 매번 프로세스를 생성하는 것보다 스레드를 생성하는 것이 효율적이며, 특히 멀티 프로세서 환경에서는 더욱 효과가 탁월하다. 스레드 간의 통신이 필요한 경우 전역 변수를 이용하여 쉽게 데이터를 주고받을 수 있다. 프로세스 간의 통신은 IPC 등의 인터페이스가 필요하며, 이는 훨씬 비효율적인 일이 될 것이다.
스레드의 장점을 정리하면 다음과 같다.
- 응답성 : 사용자와의 대화형 프로그램을 스레드로 구현시, 상호작용에 대한 부분을 스레드로 구현하여 응답성이 뛰어남
- 자원 공유 : 프로세스 간의 통신에 큰 자원이 필요하다. 스레드 간에는 자원 공유가 가능하여, 이는 큰 이점임
- 경제성 : 프로세스를 생성하는 것보다 스레드를 생성하는 시간이 적게 걸림
- 규모 가변성 : multi processor 에서의 multi threading 은 병렬성을 증가 시킴
이와 같이 프로세스 내의 스레드 간에는 전역 변수 및 메모리 공간을 공유할 수 있다. 이는 큰 장점이지만, 개발자로써는 큰 문제의 여지가 생긴다. 공유 되는 자원은 항상 충돌의 문제가 생긴다. 따라서 스레드 간에 통신 간에 충돌 문제가 발생하지 않도록 동기화 설계를 잘 고려하여 문제가 발생하지 않도록 하여야 한다. 동기화가 고려되지 않은 변수나 메모리의 공유는 오류를 발생시키며, multi thread 환경에서 자칫 디버깅이 어려운 상황을 만들 수 있다.
리눅스 커널에서는 이런 동기화를 해결하기 위한 여러 매커니즘을 제공한다. 이는 뒤에 다시 정리하기로 한다.
댓글 없음:
댓글 쓰기