1. 스레드와 프로세스
+커널
커널은 운영 체제의 일부로 HW와 프로세스의 운용을 위한 SW이다. 운영 체제의 복잡한 하드웨어 내부를 일관되고 추상적으로 볼 수 있도록 인터페이스를 제공한다. 이 추상화는 여러 장비에서 작동하는 프로그램을 짜는 것을 돕는다. 시스템의 자원은 제한되어 있지만 동작되고 있는 프로그램은 많기 때문에 커널은 한 프로그램이 언제 얼마큼 자원을 써야 할지 결정하고 운영해야 한다.
커널은 시스템이 기동될 때 부트 프로그램에 의해 구동되며 메모리에 상주한다. 기본적으로 프로세스와 파일 관리를 하며 그 밖에 입출력 장치관리, 메모리 관리 및 시스템 호출 인터페이스 기능을 수행한다.
스레드
스레드(thread)란 프로세스(process) 내에서 실제로 작업을 수행하는 주체를 의미한다. 모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행하며, (따라서 스레드의 수는 프로세스의 수 이상이 된다.) 컴퓨터에서는 기본적으로 여러 개의 프로세스가 실행되고 있다. 프로세스가 실행이 된다는 의미는 해당 명령어가 CPU에 의해서 수행이 된다는 것인데, 이를 수행해주는 역할을 하는 객체가 ‘스레드’이다. 스레드는 여러 개가 동시에 수행되는 것처럼 보이지만 실제로는 순차적으로 수행이 된다. (동시에 수행할 수 있는 것은 코어의 개념과 연관되어 있다.) 멀티 스레드는 여러 개의 스레드를 한 프로세스 내에서 처리하는 것을 의미한다. 순차적 수행을 위해서 기존의 수행을 멈추고 다음 스레드에게 CPU사용권을 넘겨줘야 한다. 이를 위해서 현재 수행되고 있는 레지스트리나 CPU내의 값의 정보를 남겨둬야 하는데, 이 상태를 ‘컨텍스트’라고 하고 이것을 남기고 다음 환경으로 복원하는 과정을 ‘문맥 교환 (Context Switching)’이라고 한다.
여러 프로그램, 여러 개의 어플리케이션이 동시에 수행을 요구하고 CPU의 사용을 요구할 때 어떻게 할 것인지를 반영하여 적절하게 CPU사용을 할 수 있도록 시간을 배분해주는 것이 ‘스케쥴링’이다. 스케쥴링은 어떤 어플리케이션을 먼저 수행할 것인가? 그리고 어떻게 효율적으로 수행중인 어플리케이션을 중지 시키고 다음 어플리케이션을 수행할 수 있을 것인지에 대한 것이다.
사용자 레벨 스레드 (User-Level Thread)
사용자 스레드는 커널 영역의 상위에서 지원되며 일반적으로 사용자 레벨의 라이브러리를 통해 구현되며, 라이브러리는 스레드의 생성 및 스케줄링 등에 관한 관리 기능을 제공한다. 동일한 메모리 영역에서 스레드가 생성 및 관리되므로 속도가 빠른 장점이 있는 반면, 여러 개의 사용자 스레드 중 하나의 스레드가 시스템 호출 등으로 중단되면 나머지 모든 스레드 역시 중단되는 단점이 있다. 이는 커널이 프로세스 내부의 스레드를 인식하지 못하며 해당 프로세스를 대기 상태로 전환시키기 때문이다.
커널 레벨 스레드 (Kernel-Level Thread)
커널 스레드는 운영체제가 지원하는 스레드 기능으로 구현되며, 커널이 스레드의 생성 및 스케줄링 등을 관리한다. 스레드가 시스템 호출 등으로 중단되더라도, 커널은 프로세스 내의 다른 스레드를 중단시키지 않고 계속 실행시켜준다. 다중처리기 환경에서 커널은 여러 개의 스레드를 각각 다른 처리기에 할당할 수 있다. 다만, 사용자 스레드에 비해 생성 및 관리하는 것이 느리다.
스레드 데이터
-스레드 기본 데이터
스레드도 프로세스와 마찬가지로 하나의 실행 흐름이므로 실행과 관련된 데이터가 필요하다. 스레드는 자신만의 고유한 스레드 ID, 프로그램 카운터, 레지스터 집합, 스택을 가진다. 코드, 데이터, 파일 등 기타 자원은 프로세스 내의 다른 스레드와 공유한다.
-스레드 특정 데이터
하나의 스레드에만 연관된 데이터를 스레드 특정 데이터( TSD)라고 한다. 멀티스레드 프로그래밍 환경에서 모든 스레드는 프로세스의 데이터를 공유하고 있지만, 특별한 경우에는 개별 스레드만의 자료 공간이 필요하다. 예를 들어 여러 개의 트랜잭션을 스레드로 처리할 경우, 각각의 트랜잭션 ID를 기억하고 있어야 하는데, 이때 TSD가 필요하다. TSD는 여러 스레드 라이브러리들이 지원하는 기능 중의 하나이다.
스레드도 메모리를 보유하고 있기 때문에 스레드를 무제한으로 만들 수 없다. 프로세스가 많아질 때 스레드 풀을 이용해서 성능을 향상시킬 수 있다. 스레드 풀이란 작업 처리에 이용되는 스레드를 제한된 수만큼 정해놓고 작업 큐에 들어오는 작업들을 스레드가 하나씩 맡아 처리하는 방식이다.
프로그램에서 사용자로부터 들어온 요청을 작업 큐에 넣게되고, Task를 미리 생성해 놓은 Thread들에게 할당한다. 이렇게 작업을 하게되면 작업 처리 요청이 폭증하게 되어도 스레드의 전체 개수를 제한하여 하나씩 처리하는 방식이므로 시스템 성능이 급격하게 저하되는 것을 방지한다.
프로세스
프로세스는 동작 중인 프로그램, 혹은 프로그램의 일부 명령어가 메모리로 올라간 상태로, 특정 메모리 공간에 작동 중인 프로그램의 코드를 적재하고 명령어를 하나씩 수행하는 상태를 의미하며, 프로세서는 프로그램을 동작할 수 있도록 해주는 HW를 의미한다. 프로세스 간에는 각 프로세스의 데이터 접근이 불가하다.
멀티 프로세스라고 하면 하나의 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것을 의미한다. 여러 개의 프로세스 중 한 프로세스에 문제가 발생하면 해당 프로세스만 타격을 입고 영향이 확산되지 않는다는 장점이 존재하나, 문맥 전환에서 오버헤드가 발생한다. 이는 프로세스가 각각의 독립된 영역을 가지고 있고 프로세스 간 공유하는 메모리가 없기 때문에 생기는 문제점이다.
멀티프로세스와 멀티스레드는 양쪽 모두 여러 흐름이 동시에 진행된다는 공통점을 가지고 있다. 멀티프로세스에서 각 프로세스는 독립적으로 실행되며 각각 별개의 메모리를 차지하고 있는다. 그러나 멀티스레드는 프로세스 내의 메모리를 공유해 사용할 수 있다. 또한 프로세스 간의 전환 속도보다 스레드 간의 전환 속도가 빠르다는 장점이 존재한다.(스레드 간에는 스택 영역을 제외한 모든 메모리를 공유하기 때문에) 또한 멀티스레드는 CPU가 여러 개일 경우에 각각의 CPU가 스레드 하나씩을 담당하는 방법으로 속도를 높일 수 있다는 것이다. 이러한 시스템에서는 여러 스레드가 실제 시간상으로 동시에 수행될 수 있기 때문이다.
스레드는 사용자에 대한 응답성 향상과 프로세스의 데이터를 모두 접근 가능하다는 자원 공유 효율이 높다는 점, 작업이 분리되어 코드가 간결하다는 장점이 존재한다. 그러나 스레드를 많이 생성하면 문맥 전환이 빈번해져 성능이 저하될 수 있다는 점과 한 스레드에 문제가 존재하면 다른 스레드에도 영향을 미칠 수 있다는 단점이 존재한다.
그러나 멀티스레드는 각각의 스레드 중 어떤 것이 먼저 실행될지 그 순서를 알 수 없다는 단점이 존재한다.
Reference
[운영체제] 프로세스와 스레드 스케줄링
IT 기술 노트
스레드와 동기화 (Thread)
https://www.fun-coding.org/thread.html#gsc.tab=0