운영체제 수업 + Operating System Concepts 10E 정리 내용
Operating System Ch04 : Thread & Concurrency
Process
1. Heavy-weight
- A process includes many things
- address space
- OS resource
- Hardware execution state -> PCB
- Create a new process is costly
- 새롭게 프로세스를 만들면 PCB를 새롭게 만들고 메모리 할당을 해줘야 하는 등의 작업을 통해 data 들을 allocate 하고, initialize 해야 하기 때문이다.
- Inter-process communication is costly
- Process간의 협력을 할때도 kernel의 도움이 필요하다.
Thread Concept: Key Idea
1. Separate the concept of a process from its execution state
- Process가 무겁다는 단점을 극복하기 위해서 생긴 개념
fork()
를 통하면, 또 다른 process를 새롭게 만들어서 진행하게 되는데 이런 과정이 무거운 작업이기 때문에 process를 하나 더 만드는 것이 아니라, 한 process안에서 thread를 여러개 생성하는 방식을 생각하게 되었다.
- 처음에는 LWP (light weight process)라는 이름으로 생겼다가 thread라는 이름으로 바뀌었다.
2. thread model
Single and Multithread Processes
1. Single-threaded process
- 하나의 function이 시작하면, 해당 function이 return 을 완료한 후 다음 function이 실행된다.
2. Multithreaded Processes
- 각 function을 가지고 각각 thread를 만든다.
- 하나의 process 안에서 두개의 function이 동시에 동작할 수 있다.
- cf) 보통 thread로 만드는 function은 무한루프로 구성된다.
3. Single and Multithread Structure
- single-threaded
- 하나의 path당 모든 정보들이 들어가게 된다.
- multithreaded
- code, data, files등의 process의 기반이 되는 정보는 공유한다.
- 실행 path가 여러 개 이기 때문에(각기 다른 동작을 하는 path) stack과 register는 다른 것을 사용 한다.
- 구조적으로 multi-process보다 가벼운 구조이다.
4. Address Space with Threads
- code, static data, heap은 공유한다.
- stack은 thread당 적당한 gap을 두고 메모리를 차지한다.
- 한 thread안에서 새로운 function을 계속 부를 수 있기 때문에 다른 thread간에 공간을 띄워둔다.
- 각기 다른 stack pointer 가짐
-> 한 thread를 실행하다가 다른 thread를 실행하면 이전 thread의 정보를 저장해 두는 곳이 필요하기 때문에
Concurrent Servers
1. Multiprocess Model
- Web server example
- multiprocess로 만드는 이유는 하나의 process가 실행되면, 해당 process가 끝나기 이전까지 다른 process는 무조건 기다려야 하기 때문에 느리다.
- ex) main process 진행 중에 child process를 만들어달라는 요청으로 인해 10의 시간을 사용
-> 만들어진 child process는 3의 시간 동안 진행하고 끝남
-> parent process가 10의 시간을 투자한 것 치고는 낭비가 심하다.
-> thread의 개념 생김
2. Multiprocess vs Multithread
- Windows는 multiprocess를 할 수 없다.
fork()
가 없기 때문에 (부모와 자식 관계가 없다)
- multithread 방식으로 발전
3. Multithread Model
thread_fork()
: 새로운 thread 만들기
- main path가 동작 중에 request가 들어오면, 새로운 thread를 만들고 다른 path로 동작을 실행하다가 동작을 다 하면 새롭게 만들어진 thread는 사라진다.
Process and Thread Code
1. Single-process
2. Multi-process
fork()
한 값을 0과 비교해서 child process 인지를 확인하고 parent와 child는 다른 과정을 진행한다.
- child :
DoCmd();
, exit(0);
을 하지 않으면, fork()
동작이 무한을 반복된다.
- parent :
wait();
, conditional compilation 응용 가능
3. Multi-Threads
- pthread는 POSIX 표준 함수
pthread_t()
: PCB
pthread_create(PCB값, 만들어진 thread의 attribute, thread로 만들 함수 이름, 함수에 필요한 parameter)
- 함수에 필요한 parameter의 경우 하나의 pointer 변수 여야 한다.
pthread_join()
: wait이랑 같은 역할 (다른 thread를 기다림)
4. Arduino example
- single path
loop()
안에서 각자 다른 동작을 하는 것을 만듬
setup()
에서 pinMode()
실행
- multi path
- 각자 다른 동작을 무한루프를 도는 function으로 만든다.
setup()
에서 xTaskCreate()
실행
-> 두 개의 task를 만들고 실행
xTaskCreate()
: 아두이노에서 지원하는 multi-tasking 함수
vTaskStartScheduler()
: 스케줄링과 유사한 역할 담당
Multicore Programming
1. Concurrent execution on a single-core system
- 하나의 코어에서 스케줄러에 따라 thread가 번갈아가면서 실행된다.
2. Parallel execution on a multicore system
- 여러 개의 코어가 thread를 나눠서 실행한다. -> 빠르다
- 발전된 방식
3. Data VS Task Parallelism
- Data : super computer의 parallel system, deep learning
- Task : 1:1 메신저 system, data를 공유하는 방식
Parallel Programming
1. Task Parallelism
2. Data Parallelism
- OpenMP (Open Multi-Processing)
- Open MPI (Message Passing Interface)
- SIMD (Single Instruction Multiple Data)
- GPGPU (General Purpose computing on GPUs)
- CUDA (Compute Unified Device Architecture)
- OpenCL (Open Computing Language)
User Threads
1. Thread management done by user-level threads library
- 초기에 kernel에 thread 개념을 넣는 것이 개발적으로 어렵다.
-> 라이브러리 형태로 개발
-> application 형태가 되기 때문에 process에 kernel이 할 일을 대신 하는 작업이 추가되므로 process가 이전보다 무거워진다.
-> 과거에만 사용하던 방식이다.
- kernel은 thread가 무슨 개념인지 모른다.
(문제점)
thread가 3개 있는 process의 경우 thread1 실행 시 IO요청이 오면 kernel이 올라와서 처리하게 된다.
-> kernel은 thread의 존재를 모르기 때문에 thread2,3은 계속 waiting만 하게 된다. (multithread의 의미가 사라진다는 뜻)
2. Example
- POSIX Pthreads
- Mach C-thread
- Solaris threads
Kernel Threads
1. Supported by the kernel
- thread의 생성과 관리를 kernel이 해준다.
-> system call이 필요하다.
- kernel이 process와 thread를 둘 다 선정하고 관리
2. Example
- Windows 95/98/NT/2000
- Solaris
- Tru64 UNIX
- BeOS
- Linux
User level VS Kernel Thread
1. User-Level threads
- OS 관점에서는 가벼워진다. (작고 빠름)
- OS는 thread의 존재를 모른다.
- 온전한 의미로서 multithreading이 아니다.
2. Kernel-Level threads
- 온전한 의미로서 multithreading
- OS의 스케줄러가 관리해준다.
- multi-process보다는 가볍지만, 이전보다는 kernel이 무거워진다.
Multithreading Models
1. Many-to-One
2. One-to-One
- kernel-level thread
- 현재 많이 사용하는 방식 (Windows)
3. Many-to-Many
- 새로운 방식, but 큰 의미가 없었다.
- kernel-level thread
- Linux
4. Two-level
- Many-to-Many + One-to-One
Threading Issues
1. Semantics of fork() and exec() system call
ex) thread가 5개인 process가 fork()
되는 경우
1) thread가 5개인 process를 하나 더 만들기
2) thread만 하나 더 만들기
-> 두 방식 모두 가능
-> 표준이 없기 때문에 개발자들의 마음이다.
-> 암묵적으로 multithreading이 일어나는 경우는 fork()
하지 않는 룰이 있다.
2. Thread cancellation
3. Signal handing
4. Thread pools
5. Thread specific data
Pthreads
- Thread creation/termination
- Mutex,Condition variables : 동기화 문제
Window Threads
HANDLE CreateThread()
void ExitThread()
Java Threads
Threads Design Space