- thread: single unique execution context
Motivation
- thread는 여러 작업을 한번에(multiples things at once) 처리할 수 있도록 해준다.
- multiprocessing과 multiprogramming은 다르다. threads를 "concurrently" 실행시킨다는 것은? 스케줄러가 어떤 순서로든 interleaving하여 실행할 수 있는 것이다. -> 따라서 correctness에 대해 생각해야 한다.
- concurrency is not parallelism! concurrency는 여러 개를 한 번에 한다는 것이고, parellelism은 여러 개를 동시에(simultaneously) 한다는 것이다.
- thread를 만들어 주게 되면 마치 "또 다른 CPU"가 구동하는 것처럼 작동함에 따라, 스케줄러가 적절히 interleave하여 실행이 된다.
Threads mask IO latency
- thread는 RUNNING, READY, BLOCKED의 세 가지 상태가 있다. thread가 I/O가 끝나기를 기다리는 동안은 OS가 이를 BLOCKED로 만들어 두고, I/O가 끝나면 READY로 바꾼다.
- BLOCKED된 동안에는 스케줄러가 다른 thread를 실행시켜준다.
OS Library API for Threads
- process가 OS library를 통해 system call을 해서 새로운 thread를 만든다. 새로운 thread들은 process의 일부로서 address space를 공유한다.
pthread_create
,pthread_exit
,pthread_join
- pthread_create를 call하게 되면, system call을 통해 kernel이 새로운 thread를 만들어준다.
- main thread가 여러 thread들을 만들면 그것들이 exit하기를 기다리다가 종료하면 다시 join하는 구조다.
Thread State
- content of memory(global variables, heap) 및 I/O state는 address space 내에서 모든 thread가 공유한다.
- CPU register, execution stack은 각 thread에게 "private"한 것으로, TCB(Thread Control Block)내에 저장된다.
- 여기서 execution stack이란 parameters, temporary variables가 담기는 곳
Interleaving and Nondeterminism
- 프로그래머가 보기에는 thread들이 각각 프로세서를 갖고 모두 동시에 진행되는 것처럼 보이지만, 실제로는 일부만 running이고 나머지는 ready 상태다. 그래서 여기서 correctness를 보장하도록 해야 한다.
- non-determinism: 스케줄러는 in any order로 실행하고, thread를 아무 때나 전환할 수 있다.
- independent thread(state를 공유하지 않음)는 deterministic, reproducible condition이지만, cooperating thread(state가 여러 thread간 공유)는 그렇지 않음 => race condition이 발생할 수 있다
- 주요 개념들
- synchronization: coordination among threads
- mutual exclusion: 어느 순간에 하나의 thread만이 특정한 행동을 할 수 있게 함(나머지를 모두 배제)
- critical section: 어느 순간에 하나의 thread만이 실행할 수 있는 코드
- lock: 어느 순간에 하나의 thread만이 갖고 있을 수 있는 객체
- lock provide 2 atomic operations
- lock.acquire(): lock이 free가 될 때까지 기다린 다음에 점유
- lock.release(): lock을 들고 있는 thread가 free할 수 있음
pthread_mutex_init
,pthread_mutex_lock
,pthread_mutex_unlock
Process
- 첫 프로세스(init)은 kernel에 의해 시작되며, 이후 모든 프로세스는 다른 프로세스에 의해 시작됨.
pid_t fork()
: 현재의 process를 복사하며, 다른 pid를 가짐. 반환값이 0이면 child process, 양수면 parent process(정확히는 child process의 pid다), 음수면 에러
'컴퓨터 > 운영체제' 카테고리의 다른 글
[UCB CS162 OS] Lec07 Synchronization(2) (0) | 2024.01.12 |
---|---|
[UCB CS162 OS] Lec06 Synchronization(1) (0) | 2024.01.11 |
[UCB CS162 OS] Lec05 IPC, Pipes and Sockets (0) | 2024.01.09 |
[UCB CS162 OS] Lec04 Files & I/O (0) | 2024.01.05 |
댓글