예전에는 하나의 프로세스가 하나의 스레드를 가진 단일 스레드 형식이었습니다.
그러나 거의 모든 현대 운영체제는 이제 한 프로세스가 다중 스레드를 포함하는 특성을 제공합니다.
스레드는 CPU 이용의 기본 단위
. 프로세스 내에서 실행되는 여러 흐름의 단위
각 스레드는 스레드 ID, 프로그램 카운터, 레지스터 집합, 스택으로 구성되어있음
같은 프로세스에 속하는 스레드는 서로 코드, 데이터섹션, Heap, 열린파일이나 신호와 같은 운영체제 자원들을 공유
중량 프로세스 : 단일 스레드를 가진 프로세스
경량 프로세서 : 하나의 프로세스가 다수의 제어 스레드를 가진 프로세스 (멀티스레드, 다중스레드). 동시에 여러 작업들을 수행
예를들어 웹서버는 수많은 클라이언트로부터 요청을 받습니다. 만약 단일 프로세스 프로세스로 작동한다면, 자신의 단일 프로세스로 한번에 하나의 클라이언트만 서비스 할 수 있게되어 오랫동안 기다려야 합니다.
멀티 프로세스
서버에서 서비스 요청이 들어오면, 프로세스는 그 요청을 수행하기 위해 별도의 프로세스를 생성하는건 어떨까요? 이런 방식을 멀티 프로세싱
라고 합니다. 안타깝지만 Context Switching과정에서의 오버헤드와 프로세스 사이의 통신이 어렵고 자원적으로 낭비입니다.
멀티스레드
따라서 대부분의 프로그램은 하나의 프로세스안에 여러개의 스레드로 구성해서 처리하는 방식을 사용합니다. 이를 멀티 스레딩
라고 합니다. 자원을 공유해서 효과적이고, 통신간 비용이 적습니다. 구체적인 장단점은 아래에서 확인해보도록 합시다.
이미지 출처 : https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html
곰곰히 생각해보면 결국 프로세스와는 다르게 스레드는 자원을 공유하기 때문에 여러 부가적인 장점들이 생기게 된다는 것을 알 수 있습니다.
동기화 문제에 대해서는 나중에 자세히 다룰것입니다.
멀티코어는 CPU안에 코어가 여러개 있는 형태를 의미합니다. 당장 멀리 갈 것도 없이 Windows 기준으로 작업 관리자를 열어 보면 실행 중인 프로그램(프로세스)들이 코어 단위가 아닌 스레드 단위
로 취급하고 있습니다.
제 컴퓨터 같은 경우에는 코어의 개수가 4개인것을 볼 수 있습니다.
멀티코어를 더 효율적으로 사용할 수 있고 병행 실행을 더 향상 시킬 수 있는 기법을 제공하는게 바로 멀티스레드 프로그래밍입니다.
원래는 하나의 코어는 한번에 오직 하나의 스레드만 실행 할 수 있었습니다. 그러다가 2008년 1세대 코어 i 시리즈부터 하이퍼스레딩이 다시 도입되면서 코어 개수 = 스레드 개수
가 항상 성립되는 것은 아니게 되었습니다. 덕분에 여러 스레드가 코어에 적재됨으로써 빠른 문맥 교환이 가능해졌습니다.
결론적으로 CPU에 박힌 코어 여러 개의 성능을 제대로 끌어내려면 여러 개의 코어에게 일거리를 효율적으로 배분하도록 프로그램을 멀티스레딩 구조로 짜 줘야 합니다.
단일 코어에서는 병행실행(Concurrency)
을 통해서 모든 테스크가 진행하게끔 함으로서 하나 이상의 테스크를 수행했었습니다. 마치 병렬 실행이 되는 듯한 착각이 들게 되었죠.
그러다가 멀티코어에서 진짜로 병렬실행(Parallelism)
을 지원하게 되었습니다. 동시에 한개이상의 일을 수행할 수 있게된것이죠. 현대에서는 하이퍼스레딩 기술로 코어당 2개의 스레드를 지원해서 더 빠른 문맥 교환이 가능해졌습니다.
사실 정리하면서도 이게 맞는지 헷갈릴때가 많습니다. 그만큼 프로세스와 스레드는 중요하면서도 어려운 개념인 듯 합니다. 여기서 끊고 머리속을 정리한다음 스레드 모델과 스레드 라이브러리를 활용한 스레드 프로그래밍에 대해 마저 공부해보도록 하겠습니다.