현대의 computer system은 기본적으로 Multi-threaded programing 지원
✔︎ process
- 독립적으로 구색을 다 갖춘 수행주체
- IPC도 고려해야 함.
- context switching 할 때 overhead하느라 낭비 많음.
✔︎ thread
- process의 약식으로 구성된 수행 줄기
- 만든 이유: 일을 병렬화로 진행하고 싶은데 process를 생성하려면 필요한 것들이 너무 많음 → 적은 일을 수행하기 위해 간단한 줄기를 만듦.
📍 Thread
: light-weigth process (LWP)
- 정식 process에 비해서 간결 → 생성속도 빠름
- multi thread에서 각 thread는 고유의
- 동일 process에 속한 다른 thread와
-
code section
-
data section
-
기타 OS resource
를 공유
✅ 이점
- responsiveness (응답 특성이 좋아짐)
- interactive system (대화형)에서 한 수행이 block되더라도 나머지 부분이 수행될 수 있도록 한다
- ex. 다른 기능도 멈춰버리면 X
-
resource sharing 종류
: 동일 process에 속한 resource 공유
-
Economy (경제성)
: 비용이 적게 든다 (= 시간적, 공간적 유리)
- 정식 process보다 속도 (context, 생성 switching) 빠름
-
scalability (확장성)
: multi-processor architecture에 활용 가능
- 규모의 확장이 용이함
- thread마다 CPU가 다 다름
- single thread에 비하여 이런 장점이 있음
✅ 1. User thread
- kernel이 user thread를 인지하지 못할 수도 있음
- kernel의 지원을 받지 않는 thread → 하나 끊기면 다 끊김
- user level 상에서만 돌아감
- user level에서 thread scheduling을 지원해서 OS는 이 존재를 알지 못함.
- OS의 지원을 받지 않음
- 생성 빠름 (kernel thread보다)
✅ 2. kernel thread
- OS가 실질적으로 관리하는 thread
- 실질적으로 context switching이 일어남.
- multi processor에 적용 용이
- 한 개의 thread가 block 되어도 다른 thread는 수행을 계속할 수 있음
✅ single thread process vs multi thread process
- single thread process
- multi thread process
- 수행 줄기가 여러 개
- register, stack이 별도로 있음
✅ libraries
1. kernel support 없이 user space 상에 두는 Library
- 함수의 실행이 user space의 local funtion으로 고려
- 모든 code와 data structure가 user space에 존재
- user space: system space funtion space
2. OS의 지원을 받는 kernel level library
- code와 data structure가 kernle space에
- 함수의 실행은 system call로써 이루어짐
✅ implict threading
: programmer가 threading을 하기 위해서 task를 나누고 process간 comm 등을 처리하는 부담을 줄일 수 있도록 언어에서 자동으로 threading 기능 지원
방법 1. thread pool
: 일정 갯수의 thread를 미리 만들어 두는 것
- servel가 일정 갯수의 thread를 사전에 미리 만들어 놓고 각 thread는 작업이 주어지기를 기다림
- 장점
- 실제 작업이 주어졌을 때 thread를 생성하는 시간이 필요 없어짐 (이미 만들어져있음)
- system의 thread 총 갯수 제어가 용이
- task 수행의 다양한 전략이 가능함.
- thread pool의 적정 thread 수는
-
CPU 갯수
-
memory 용량
-
예상 요청 갯수
를 고려해서 만든다
방법 2. Open MP (multi-Processing)
- compiler directive 형태로 지원하는 paraller processing 형식
- compiler directive : compiler만 이해하는 process 명령
- directive : pre process
- ex. comment 제거, #include (in C) 등
- paraller processing 의미 : 동시수행
✅ thread issues (고려사항)
- multi threaded program이 process 생성 명령을 수행하면
- signal handling
- signal: unix에서 process에 어떤 event 발생 상황을 알림
- synchronous (동기적) signal: 발생되는 시점이 명확한 것
- asynchronous signla : 외부 event에 의해 생성
- signal handler
- 1) default signal handler
- 2) user-defined signal handler
✅ thread canellatin (thread 취소, 종료)
: 완료되지 않은 thread를 종료시키는 개념
-
asynchronous
: 종료가 필요한 시점에 즉각 한 thread가 다른 한 target thread를 종료시키는
-
deffered
: target thread가 스스로 주기적으로 자신이 종료해야 하는지 check하고 소정의 종료 절차(resource 처리)를 수행하는 개념
- 1번에 비해 2번의 장점 = 안전 (system의 resource)
- 2번에 비해 1번의 장점 = 즉각 반응 가능
✅ Thread Local Storage (TLS)
: thread가 갖는 자신만의 저장 장치, thread마다 고유하게 저장되는 저장공간
- 자신만의 작은 저장 공간
- 각자 고유한 data 복사본을 가질 수 있다.
- thread는 원 process의 data section 공유 → 상황에 따라 어떤 data에 의하여 자신만의 copy를 유지할 필요가 있다.
- thread pool에서 유용하다
- static data와 유사
✅ Scheduler Activations
: application내에서 kernle thread의 수를 적절하게 유지할 수 있도록 도와줌.
LWP
: 경량화 process
- user thread와 kernel thread 사이에서 CPU 역할을 해줌
- processor가 아니지만 processor처럼 보이는 수행을 함
✏️ 용어정리
✔︎ multi-processor
✔︎ multi-process
: 한 program 내에서 process가 여러 개
- 여러 개의 process 동시 실행
- 독립적인 공간이 있음 (text, data, stack 영역, heap 영역)
- 서로에게 영향을 주지 않음 (영향을 미치려면 IPC 고려해야 함)
✔︎ multi-thread
- thread 여러 개 process안에서 수행 줄기
- 수행 흐름 독립적
- 공유 편함
- 한 process 내에서 thread 여러 개
- 자원은 process 안에서 공유 중
📍 multi-core
: CPU 안에 칩이 여러 개 있는 것
- processor = 일꾼, core = 일꾼의 팔
✅ multi core를 활용하는 programming을 위하여 필요한 내용
-
Dviding activity
: 작업을 여러 개의 current task로 분할하여 각 core에서 실행하도록 고려해야 함
-
Balance
: 병렬처리가 의미가 있도록
- 작업을 여러 개로 분할하고 한 명에게 몰아주면 병렬처리의 의미가 없어지기 때문에 balance에 맞게 분할을 해야 함.
-
data splitting (data 쪼개기)
: 각 core에서 실행할 data 분리
-
data dependency
: task의 종속성
-
testing & debugging
: single CPU에 비해서 복잡해짐 (b/c. execution path가 복잡해짐)
✅ Multi-core Programming
✅ core를 여러 개 둠으로써 얻어지는 성능 개선 효과
📍 multi threading Model
1. many to one
: user 많이 kernle 하나
- n 개의 user thread가 하나의 kernel thread에 mapping
- user 입장에서는 여러 개로 보이지만 실제로는 한 개의 thread
- kernel에서는 multi-thread를 인지하지 못함
- 사용자의 입장에서는 multi-thread처럼 보임
- os는 kernel thread만 관리하니까 os에서는 하나의 kernel thread만 인지한다는 뜻
- 여러개의 user thread를 인지하지 못합니당
- 장점
- 생성이 빠르다 (b/c. thread하나만 생성을 하면 되기 때문)
- 단점
- 한 개 thread가 block되면 전체가 block 됨
2. one to one
: user thread와 kernel thread가 1:1 mapping
- many-to-one에 비해 concurrency(동시수행)가 개선됨
- 단점
3. many-to-many
: 여러 개의 user
- 장점
- 한 개의 thread가 block 되어도 진행 가능
- 단점
+) two level model
- many-to-many로 하면서 one-to-one도 허용해주는
- many-to-many로 수행을 하되, one-to-one도 허용!
📍 Thread libraries
: programmer가 thread를 생성
방법 1 (언어 level 지원)
- kernel support 없이 user space 상에 두는 library
- system call 아님.
- 언어에서 지원
- 모든 code와 data structure가 user space 상에 존재
- user space : system space, function space
- function의 실행이 user space의 local function으로 고려
방법 2 (system level 지원)
- OS의 지원을 받는 kernel level library
- code와 data structure가 kernel space에
- 함수의 실행은 system call로써 이루어짐
📍implict threading
: programmer가 task를 나누고 process 간 commnication 등을 처리하는 부담을 줄일 수 있도록 언어에서 자동으로 threading 기능 지원
▪︎ thread pool
: server가 일정 개수의 thread를 사전에 미리 만들어놓고 각 thread는 작업이 주어지기를 기다림
→ 일정 개수를 미리 생성해두는 것.
▫︎ 이점
-
효율적이다
b/c. request를 처리할 때 새롭게 생성하지 않으므로 속도가 빠르다.
-
system thread 총 개수 제어가 용이
- b/c. 미리 몇 개 만들어두면 그 이상 만들지 않아도 되기 때문
-
task 수행 관련한 다양한 전략이 가능
b/c. thread를 생성하는 과정과, 실행될 task를 결정하는 과정이 분리되므로 다양한 전략이 가능하다 (ex. 일정 시간 지연 후 실행, 주기적 실행)
▫︎ thread pool의 적정 thread 수를 위해 고려해야 하는 것들
- CPU 갯수
- memory 용량 (여러개 동시 수행하면 memory 많이 필요하기 때문)
- 예상 요청 갯수
📍 Open MP (multi processing)
- compiler directive 형태로 지원하는 paraller processing 형식
- compiler directive : compiler만 이해하는 process 명령
- directive : pre processing
- paraller processing = 동시수행
📍 Thread issues (고려사항)
1. multi-threaded program이 process 명령을 수행하면
- 모든 thread를 중복 생성
- new process는 single thread로
- 이미 2줄기 수행중인데 다시 생성하라고 하면, 다 중복할 것이냐, 새로운 거 하나 생성할것이냐
2. signal handling
- signal : unix에서 process에 어떤 event 발생을 앙ㄹ림
- synchronous signal
- illegal memory access
- division
- asynchronous signal
- 외부 event에 의해 생성 (ex. control-C)
3. signla handler
-
default signal handler
-
user-defined signal handler
: signa이 발생했을 때 수행되는 action을 user가 정의한 내용으로 overriding 가능
📍 thread cancellation (= thread취소, thread 종료)
: 완료되지 않은 thread를 종료시키는 개념
형식1. asynchronous cancellation
: 종료가 필요한 시점에 즉각 한 thread가 다른 target thread를 종료시키는
- 비동기 (수행시점이 논리에 근거하지 않는, 돌발적인)
형식2. deffered cancellation
: target thread가 스스로 주기적으로 자신이 종료해야 하는지 check하고 소정의 종료 절차(resource처리)를 수행하는 개념
📍 thread local storage (TLS)
: thread가 갖는 자신만의 저장 장치 (고유한 data 복사본)
- thread는 원 process의 data section 공유 → 상황에 따라 어떤 data에 의하여 자신만의 copy를 유지할 필요가 있음.
- 각자 고유한 data를 가질 수 있다는 의미