Thread
CPU utilization 의 기본 단위로, thread ID, PC(Program Counter), reigster set , stack 으로 이루어져 있다.
같은 프로세스에 속한 스레드들은 프로세스의 code section, data section, open files 와 signals 같은 os 자원을 공유한다.
Linux/Unix 와 Window 같은 현대 OS 는 multithreaded programming 을 지원한다.
프로세스는 a set of threads 와 a collection of resources 라는 두 가지 구성요소로 나눌 수 있는 복합 엔티티이다.
- 실행의 단위는 스레드이다.
- 프로세스는 실행 흐름을 담당하는 메인 스레드를 가짐
- 프로세스는 실행 권한을 메인 스레드에게 넘기고, 메인 스레드가 다른 스레드를 생성하고 권한을 넘기는 식으로 작동
Procedure Calls Vs Multithreading
Similarities
- 다른 function(or thread) 에 의해 선언된 로컬 변수에 function call (or thread) 가 접근할 수 없다.
- global data 와 heap regions 은 function 과 thread 모두 접근할 수 있음
Distinction
- thread 는 자신만의 스택을 가짐
Multithreaded programming Benefit
- Responsiveness (응답성) : 일부 작업이 차단되거나 긴 작업이 일어나도 프로그램이 계속 실행되므로, 사용자에 대한 응답성이 증가한다.
- Resource sharing (자원 공유) : IPC로 통신할 수 있는 프로세서와 달리, 스레드는 기본적으로 자신이 속한 프로세스의 메모리와 자원을 공유한다.
- Economy (경제성) : 스레드는 자신이 속한 프로세스의 자원을 공유하므로, 스레드 생성과 context switching 에 더 적은 비용이 든다.
- Scalability (확장성) : 한 프로세서에서만 실행가능한 단일 스레드 프로세서와 달리, 한 프로세스를 여러 프로세서에서 실행시킬 수 있다.
Thread Library
thread library 는 프로그래머에게 스레드를 생성하고 관리하는 API 를 제공한다.
thread library 에는 두 종류가 있다.
- User-level library : library 의 모든 코드와 데이터 구조가 user space 에 존재하며, 함수를 호출하면 system call 이 아닌 local function call 이 이루어진다.
- Kernel-level library : library 의 모든 코드와 데이터 구조가 kernel space 에 존재하며, 함수를 호출하면 system call 이 이루어진다.
Example
- POSIX PThread : 과거에는 user-level library 였지만, 최근 kernel-level library
- Win32 : kernel-level library
- Java thread : kernel-level library
Multithreading Model
User-level Threads
- user-level library 에 의해 관리됨
- User-level threads 는 커널 위에서 지원되며 커널의 도움없이 관리된다.
- system call 을 하지 않음
Kernel-level Threads
- kernel 내부에서 필요에 따라 생성되고 소멸된다.
- kernel text 와 global data 를 공유하며 자신의 kernel stack 을 가진다.
- kernel scheduler 에 의해 독립적으로 스케줄링 된다
- sleep() 과 wakeup() 같은 kernel 의 sychoniztion mechanism 들을 사용한다.
user thread 와 kernel thread 사이에 관계가 존재하는데, 관계의 종류에는 Many-to-One, One-to-One, Many-to-Many 이 있다.
Many-to-One
여러 개의 user-level thread 가 하나의 kernerl thread 와 연결된 관계
multiple processing core 의 장점을 사용할 수 없어 잘 안 쓰임
Advantage
- thread management 가 user space 의 thread library에 의해 수행되어 효율적
Disadvantage
- thread 가 block system call 을 하면 전체 프로세서가 block 됨
- 한 번에 하나의 스레드만 kernel 에 접근할 수 있어, multicore system 에서 여러 스레드들이 병렬처리 될 수 없음
Example
- Solaris Green Threads
One-to-One
각각의 user-level thread 가 kernel thread 와 연결된 관계
Advantage
- 한 스레드가 blocking system call 을 할 때, 다른 스레드가 실행되도록 허용함.
- Many-to-One 모델보다 더 많은 동시성 제공
- multiprocessor 에서 여러 스레드를 병렬 처리 가능
Disadvantage
- user thread 를 생성하려면 대응하는 kernel thread 도 생성해야함
- context switching overhead 가 kernel thread 의 수에 의존하므로, 많은 수의 kernel thread 는 시스템 성능에 부담을 줌
Example
- Window
- Linux
Many-to-Many
여러 user-level thread 를 더 작거나 같은 수의 kernel-level thread 에 다중화하는 관계
kernel thread 수는 어플리케이션이나 머신에 의해 달라짐
Advantage
- 필요한 만큼 user thread 를 생성할 수 있고, 해당 kernel thread 가 multiprocessor 에서 병렬 실행 될 수 있음
- 한 thread 가 blocking system call 을 하면 kernel 은 다른 실행을 위해 thread 를 스케줄링함
- 제한된 수의 kernel thread 로 좋은 동시성 제공
Disadvantage
- 진짜 동시성이 아님
- 예를 들어 4-to-3 모델에서, 세 스레드가 blocking system call 을 한다면, process 는 block 된다
Two-level Model
Many-to-Many 모델과 비슷하지만, 하나의 user-level thread 를 kernel-level thread 에 바인딩 해야함
Thread Cancellation
thread cancellation 은 스레드가 완료되기 전에 스레드를 종료하는 것.
예를 들어, 여러 스레드가 동시에 db를 검색하는 중 한 스레드가 결과를 반환하면 나머지 스레드들은 취소될 수 있다.
취소되어야하는 thread 는 target thread 라고 불리며, target thread 의 취소는 두 가지 상황에서 발생함
- Asynchronous cancellation : target thread 를 즉시 종료하는 것
- Deferred cancellation : target thread 가 주기적으로 취소되어야 하는 지 확인하여 종료하는 것
Asynchronous cancellation 의 어려움은 다음같은 상황에서 발생한다.
- canceled thread 에 lock 이나 mutex 같은 resources 가 할당되었을 때
- 스레드가 다른 스레드와 공유중인 데이터를 업데이트 하는 도중에 취소될 때
OS 가 canceld thread 로부터 resource 를 회수하지만, 모든 resource 를 회수하지 않는 경우가 생겨 Resource Leakage 가 발생한다.
Defered cancelation
target thread 가 안전하게 취소될 수 있는 시점(cancellation point)인지 체크한 후에 취소가 이루어진다.
Thread Pools
웹 서버는 요청을 받을 때마다 별도의 스레드를 생성하여 요청을 처리한다. 별도의 스레드를 생성하는 것이 프로세스를 생성하는 것 보다 우수하지만, 멀티스레드 서버는 몇 가지 문제점이 있다.
- 스레드를 생성하는데 걸리는 시간과 작업을 완료하면 스레드가 폐기된다는 것
- 동시 요청을 새 스레드에서 처리되도록 허용하면, 시스템에서 동시에 활성되는 스레드 수를 제한하지 않아 시스템 resource 를 고갈시킴
이러한 문제점을 해결하기 위해 Thread Pool 을 사용할 수 있다. 스레드 풀의 동작과정은 다음과 같다.
- 시스템 시작 시 여려 스레드를 생성해 pool 에 넣어놓은 후작업을 기다린다.
- 서버가 요청을 받으면 스레드를 생성하지 않고, 요청을 스레드 풀에 전달하고 추가 요청을 기다린다.
- 풀에 사용 가능한 스레드가 있으면, 해당 스레드가 깨어나 요청을 처리한다.
- 풀에 사용 가능한 스레드가 없으면, 사용 가능한 스레드가 생길 때까지 작업을 대기한다.
- 스레드는 서비스를 완료하면 풀로 돌아가 다른 작업을 기다린다.
스레드 풀은 제출된 작업이 비동기적으로 실행될 수 있을 때 잘 작동한다.
Advantages
- 새로운 스레드를 생성하는 것보다, 존재하는 스레드를 사용해 요청을 처리하는 것이 보통 더 빠름
- 풀의 크기를 제한하여 스레드의 수를 제한할 수 있다. 이는 많은 수의 동시 스레드를 지원할 수 없는 시스템에서 중요함
참조
Silberschatz_Operating_System_Concepts_10e_2018
광운대 운영체제 강의(안우현 교수, 2021)
'COMPUTER SCIENCE > OS' 카테고리의 다른 글
[OS] Deadlock (0) | 2023.08.21 |
---|---|
[OS] Synchronization (0) | 2023.08.16 |
[OS] CPU Scheduling (0) | 2023.07.14 |
[OS] Process - IPC (Interprocess Communication) (0) | 2023.07.10 |
[OS] Process - Operations on Processes (0) | 2023.07.10 |
댓글