프로세스는 실행중인 프로그램의 인스턴스이며, 스레드는 실행되는 흐름의 단위입니다.
한 프로그램에서 둘 이상의 프로세스를 생성한다면 빈번한 context switching으로 성능 저하가 생깁니다.
그래서 스레드가 탄생했으며 스레드는 한 프로그램에서의 여러 실행흐름입니다.
스레드는 여러 영역을 공유하지만 스택은 독립적으로 소유합니다.
스레드의 공유영역
Stack(공유되지 않음)
스택은 함수 호출 시 전달되는 parameter, return address가 저장됩니다. 각 스레드는 독립적으로 함수 호출이 가능하다는 이야기가 됩니다.
PC Register(공유되지 않음)
프로그램 카운터는 명령이 수행할 지점을 가리킵니다. 스레드는 결국 스케줄러에게 다시 선점당하기 때문에 명령어가 어디까지 수행됐는지 기억해야 합니다.
Code
Code영역이 공유돼야 자신이 포함된 프로세스의 함수를 호출할 수 있습니다.
Data & Heap
전역변수와 메모리 공간을 공유합니다. 힙 영역이 공유되면 스레드 간 통신을 할 수 있게 됩니다.
IPC 없이도 통신이 가능합니다.
다중스레드
다중 스레드의 장점은 Responsiveness, Resource sharing, Economy, Scalability 네가지 부류로 나눌 수 있습니다.
응답성(responsiveness)
프로그램의 일부가 봉쇄되거나 긴 작업을 수행하더라도 프로그램 수행이 계속됩니다.
UI를 설계할 때 특히 유용합니다.
자원 공유(resource sharing)
프로세스는 공유메모리, 메시지 전달 기법을 통해야만 자원을 공유할 수 있습니다.
스레든느 자동으로 그들이 속한 프로세스의 자원과 메모리를 공유합니다.
코드와 데이터 공유의 이점은 한 응용 프로그램이 같은 주소 공간 내 여러 다른 작업을 하는 스레드를 가질 수 있다는 점입니다.
경제성(economy)
프로세스 생성보다 스레드 생성이 경제적입니다. 또한 context switching 역시 스레드 사이에서 더 빠릅니다.
규모 적응성(scalability)
다중 처리기 구조에서 각각의 스레드가 병렬수행됩니다.
Java Thread
Thread 클래스에서 파생된 새 클래스를 만들고 run() 메소드를 재정의해 스레드를 명시적으로 생성합니다.
Runnable 인터페이스의 구현체를 정의해 스레드를 명시적으로 생성합니다.
스레드 풀
다중 스레드 서버는 아직 여러 문제를 갖고 있습니다.
서비스할 때마다 스레드를 생성하는 데 소요되는 시간입니다.
최대 스레드 수를 정해야 합니다. 스레드가 무한하다면 CPU 시간, 메모리 공간 등의 시스템 자원이 고갈됩니다.
이에 대한 대안이 스레드 풀입니다.
프로세스를 시작할 때 일정한 수의 스레드들을 미리 풀로 만들어둡니다.
References
Abraham Silberschatz, Peter B. Galvin, Greg Gagne의 『Operating System Concept 10th』