-
스레드(Thread)CS/OS(운영체제) 2022. 5. 30. 16:59728x90
Process And Thread
Process(프로세스) - 실행 중인 프로그램 ( 프로그램의 인스턴스 )
- 명령 시퀀스 및 관련 시스템 리소스 집합의 실행으로 특정지어지는 활동 단위
2가지 특성
자원 소유 단위(The unit of resource Ownership) - 시간이 흐름에 따라 프로세스에는 메인 메모리, I/O 채널 , I/O 장치 및 파일과 같은 리소스의 제어 또는 소유권이 할당될 수 있음.
일정/실행 단위(The unit of scheduling / execution) - 따라서 프로세스는 실행 상태(Running,Ready, etc..)와 우선순위(Priority)를 가지며 OS에 의해 스케줄링되는 엔티티.
여태까지 포스팅 한 글에서는 Process가 단일 실행 Sequence를 가지고 있다고 가정했으나, 일반적으로 일정/실행 단위는 Thread(or lightweight process)라고 하며, 자원 소유 단위는 프로세스(or task)라고 한다.
멀티 쓰레딩(Multithreading)
- 모든 현대 OS는 프로세스가 여러 스레드를 포함할 수 있는 기능을 제공함.
- 멀티쓰레딩은 프로세스 내부에 하나 또는 더 많은 스레드가 있을 수 있음.
- 즉, 단일 프로세스 내에서 여러 개의 동시 실행 경로를 제공하는 OS의 기능임.
동시성과 병렬성(Concurrency and Parallelism)
동시성 - 동시 시스템은 모든 작업이 진행되도록 하여 두 개 이상의 작업을 지원함.
- interleaving 시 2개 이상의 스레드가 실행될 수 있는 능력을 말함.
병렬성 - 병렬 시스템은 여러 작업을 동시에 실행할 수 있음.
- overlapping 시 2개 이상의 스레드를 중복하여 실행할 수 있는 능력.
- 따라서 병렬 처리 없이 동시성이 가능함.
응용 프로그램에는 여러 개의 task가 존재하며, 다른 task가 차단 없이 진행되도록 하는 것이 좋다.
예를 들어 여러 클라이언트가 동시에 있는 busy한 웹서버를 생각해보자.
기존 single-threaded process에서는 한 번에 하나의 클라이언트만 지원할 수 있고, 클라이언트가 요청을 매우 오래 기다려야 할 수 있다. 그러나 Multi-processing solution에서는 서버가 request를 수신하면 request를 처리하기 위한 새 프로세스를 작성한다. 이를 Multi-threading solution에서는 request가 작성되면, 서버는 다른 프로세스를 작성하는 대신 요청을 처리할 새 스레드를 작성하고, 추가 request에 대한 수신을 재개한다.
멀티쓰레딩의 장점
1. 응답성(Responsiveness) - interactive한 응용 프로그램에서의 멀티쓰레딩은 일부가 차단되거나 장시간 작업을 수행하는 경우에도 프로그램을 계속 실행할 수 있고, I/O와 연산이 중복되도 문제가 없음.
RPC(Remote Procedure Calls - 시스템 SW기법)를 예를 들면 단일 스레드의 경우 프로그램은 각 서버의 응답을 차례로 기다려야 하지만, 멀티 스레딩의 경우 두 개의 응답을 동시에 기다림.
2. 생성 및 상호작용 비용(Creation/Communication Cost) - 전체 PCB를 새로 생성할 필요가 없고, 프로세스보다 전환 속도가 빠름. 공유 메모리와 같은 techniques을 통해서만 리소스를 공유할 수 있음. 메모리에서 동일한 데이터를 읽고 쓰는 방식으로 스레드간의 협업이 가능함. 하지만 독립 프로세스간의 통신은 보호 및 통신에 필요한 메커니즘을 제공하기 위해 커널의 개입이 반드시 필요함.
3. 멀티코어에서의 확장성(Scalability on Multicore) - 멀티스레딩의 장점은 멀티프로세서 구조에서 훨씬 더 강력한 이점을 가짐. 그러한 이유는 사용 가능한 프로세서의 수에 상관없이 단일 프로세서의 프로세스를 실행 가능함. 즉 동일한 어플리케이션을 여러 코어에서 실행할 수 있고, 프로세스가 여러 CPU에서 실행될 수 있음(parallelism)
멀티코어에서의 멀티스레딩을 구현하기 위한 과제
1. task 식별 - 태스크는 서로 독립되어 있어 병렬로 실행할 수 있게 구현해야 함.
2. Balance - 프로그래머는 작업이 동일한 value의 동일한 작업을 수행하도록 보장해야 함.
3. Data Dependency(데이터 의존성) - 2개 이상의 작업 간의 의존성을 검사해야 함. 한 작업이 다른 작업의 데이터에 의존할 때, 프로그래머는 작업의 실행이 데이터 종속성을 수용하도록 동기화하여 구현해야 함.
멀티코어 병렬화 Type
1. 데이터 병렬화 - 동일한 데이터의 하위 집합을 여러 컴퓨팅 코어에 분산하고, 각 코어에 대해 동일한 작업을 수행하는 데 집중하는 Type.
2. 작업(Task) 병렬화 - 데이터가 아니라, 여러 컴퓨팅 코어에 걸쳐 작업(Thread)을 포함함. 동일한 데이터에서 서로 다른 스레드가 작동할 수 있음.
멀티쓰레드 프로세스 모델
첫번째로, 각 스레드마다 분리된 스택이 필요함. PCB와 비슷하게 각 스레드마다 register value, 스레드와 관련된 scheduling, 상태 정보를 갖고 있는 분리된 thread-realated control block(TCB)이 필요함.
LWP(LightWeight Process)
새 프로세스를 생성하는 것 보다, 이미 존재하는 프로세스 안에서 새로운 스레드를 만드는게 시간이 훨씬 적게 소모됨.
프로세스 간 switch보다 동일한 프로세스 내에서 두 스레드 간 switch 성능이 더 좋음
멀티쓰레딩 모델
스레드 구현에는 2가지의 광범위한 카테고리가 있음.
ULT(User-level thread) , KLT(Kernel-level thread) , Combined
Kernel-Level Threads (KLTs)
Pure KLT 안에서, 모든 스레드 관리의 작업은 커널에 의해 수행됨.
- 커널은 프로세스 내부의 각 커널의 context 정보를 유지함.
- aplication level 안에는 스레드 관리 코드는 존재하지 않음.
- 1스레드당 1커널의 스케쥴 entity를 가짐. Ex) Windows.
커널 스레드 사이의 스위칭
- 커널 안으로 들어감 -> 커널은 실행중인 스레드의 프로세서 내용을 TCB안에 저장함 -> 커널은 실행시키기 위한 새로은 스레드를 선택함 -> 커널은 새 스레드의 레지스터를 로드하고, TCB로 부터 PC에 저장하기 위한 단계로 넘어감.
운영체제가 관리하는 스레드는 Kernel-Level threads라고 부름.
제약
1. 스레드 운영에는 여전히 시스템 콜이 요구됨. (즉, 커널로의 모드 스위치가 요구됨)
2. 세분화된 동시성을 위해 KLT는 여전히 너무 많은 오버헤드를 겪음. ( 즉, 동시성을 위해 훨씬 더 cheaper한 threads가 필요함)
User-Level Threads (ULTs)
모든 스레드 관리는 어플리케이션에 의해 수행됨.
- 스레드 라이브러리를 사용함으로써 멀티스레드를 수행할 수 있음.
- 스레드 라이브러리는 스레드를 생성하고, 파괴하는 코드를 포함하고 스레드 사이의 messages와 data를 전달하고, 스레드 실행 스케쥴링 및 스레드 context의 저장 및 복원을 포함함.
스레드 간 switch는 다음 내용을 수반함
- 라이브러리는 실행중인 스레드의 프로세서 내용을 TCB안에 저장함 -> 라이브러리는 실행하기 위한 새 스레드를 선택함 -> 라이브러리는 새 스레드의 내용을 복원하고, TCB로부터 PC에 저장하기 위한 단계로 넘어감.
그러나 커널은 관여하지 않음
장점 : 스레드 스위칭은 커널 모드를 요구하지 않음 , ULTs는 어떤 운영체제에서도 실행 가능함 , 스레드 스케쥴링은 응용 프로그램에 따라 달라질 수 있음.( 즉, 기본 OS 스케쥴러를 방해하지 않고 애플리케이션에 맞게 조정 가능 )
제약
1. 커널은 스레드의 존재를 인식하지 못함.
2. 커널은 한번에 하나의 커널 스레드만 스케쥴링할 수 있으므로 병렬 처리되지 않음.
3. ULT가 시스템 호출을 실행하면, 해당 스레드가 차단될 뿐 아니라 프로세스 내의 모든 스레드가 차단될 수 있음.
해결책
Blocking 시스템 콜을 non-blocking 시스템 콜로 전환.
KLTs Vs ULTs
KLT - 운영체제와 통합됨 , 생성/조작/동기화가 느림
ULT - 운영체제와 통합되지 않음 , 생성/조작/동기화가 빠름
프로그래밍의 정확성과 성능을 위해 KLT와 ULT의 차이를 이해하는 것이 중요함.
Combined(ULT/KLT)
몇몇 운영체제는 ULT와 KLT를 결합하여 제공함
- 스레드 생성은 유저 공간안에서 수행됨
- 싱글 애플리케이션으로부터 여러개의 ULTs들은 (더 작거나 동일한)수의 KLTs에 맵핑됨.
- 프로그래머는 KLT의 수를 조정할 수 있음.
- Solaris는 이러한 결합 전근 방식을 사용하는 운영체제의 예시임.
Thread API 예시
gcc thread.c -lpthread로 컴파일
/* bad sharing */ #include <pthread.h> #include <stdio.h> #define ITER 1000 void *thread_increment(void *arg); void *thread_decrement(void *arg); int x; int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, thread_increment, NULL); pthread_create(&tid2, NULL, thread_decrement, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); if (x != 0) printf("BOOM! counter=%d\n", x); else printf("OK counter=%d\n", x); } /* thread routine */ void * thread_increment (void *arg) { int i, val; for (i=0; i< ITER ; i++) { val = x; printf("%u: %d\n", (unsigned int) pthread_self(), val); x = val + 1; } return NULL; } void * thread_decrement (void *arg) { int i, val; for (i=0; i< ITER ; i++) { val = x; printf("%u: %d\n", (unsigned int) pthread_self(), val); x = val - 1; } return NULL; }
스레드 동기화(Thread Synchronization)
- 멀티 스레드 프로그램에서 스레드 간의 협업.
스레드가 공유 리소스에 동시에 엑세스하면 잘못된 결과가 리턴되고, race condition이 호출됨.
스레드 동기화에 대한 세부 정보는 다음 포스팅에서 후술하겠다.
728x90'CS > OS(운영체제)' 카테고리의 다른 글
동기화(Synchronization) 2 (0) 2022.06.12 동기화(Synchronization) (0) 2022.06.01 인터럽트(Interrupts) (0) 2022.04.17 컴퓨터 하드웨어(Computer Hardware) (0) 2022.04.17 Process Scheduling (0) 2022.04.12