CS โ process vs thread
๐ 05/07 โ ํ๋ก์ธ์ค์ ์ค๋ ๋์ ์ฐจ์ด์
๋ชจ์๋ฉด์ ์ฃผ์ : โํ๋ก์ธ์ค์ ์ค๋ ๋์ ์ฐจ์ด์ ์ ๋ํด์ ์ด์ผ๊ธฐ ํด์ฃผ์ธ์โ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ โ ์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ โ ๋๊ธฐํ โ ๋ฉํฐํ๋ก์ธ์ค/๋ฉํฐ์ค๋ ๋ ์ ํ โ ๊ฒ์ ์ค๋ ๋/๋ ๋ ์ค๋ ๋๊น์ง
ํ์ต ์์ญ ์ ํ์ โ ์๋ฃ๊ตฌ์กฐยทSTL์์ OSยท๋์์ฑ์ผ๋ก
13~18๋ฒ์์ STL ์ปจํ
์ด๋์ ์๊ณ ๋ฆฌ์ฆ(vector/list, find/binary_search, list::sort ๋ฑ)์ ์ ๋ฆฌํ๋ค๋ฉด, 19๋ฒ๋ถํฐ๋ ์ด์์ฒด์ (OS) ์์ญ์ผ๋ก ๋์ด๊ฐ๋๋ค. ์๋ฃ๊ตฌ์กฐ๊ฐ โ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๋ฐฐ์นํ๋โ์ ๋ฌธ์ ์๋ค๋ฉด, ๋์์ฑ์ โ์ฌ๋ฌ ์คํ ํ๋ฆ์ด ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ๊ณต์ ํ๊ณ ์ถฉ๋์ ํผํ๋โ์ ๋ฌธ์ ์
๋๋ค.
1
2
3
4
5
13~18๋ฒ STL ์ปจํ
์ด๋ยท์๊ณ ๋ฆฌ์ฆ โ ์๋ฃ๊ตฌ์กฐ ๋๋ฉ์ธ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
19๋ฒ ํ๋ก์ธ์ค vs ์ค๋ ๋ โ
โ OS ๋๋ฉ์ธ ์ง์
์ดํ ๋ฎคํ
์คยท์ธ๋งํฌ์ดยท๋ฐ๋๋ฝ / ์ค์ผ์ค๋ฌ โ ๋์์ฑ ๊น์ด
๊ฐ์ ๋ฉ๋ชจ๋ฆฌยทํ์ด์งยท์คํ vs ํ (์ฌ๋ฐฉ๋ฌธ) โ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
์ด ์ฃผ์ ๋ 11๋ฒ ์ค๋งํธ ํฌ์ธํฐ์ shared_ptr ๋ฉํฐ์ค๋ ๋ ์์ ์ฑ(์ ์ด ๋ธ๋ก atomic ์นด์ดํฐ), 16๋ฒ STL ์ปจํ ์ด๋์ ์ค๋ ๋ ์์ ์ฑ ์ปจ๋ฒค์ (๊ฐ๋ณ ์ปจํ ์ด๋๋ thread-safeํ์ง ์์)๊ณผ๋ ์ง์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ ๋จ๊ณ ๋ ๋ค์ด๊ฐ๋ฉด mutexยทlock_guardยทscoped_lock(GRAPH_REPORT์ Community 18ยท23) ๊ฐ์ RAII ๋ฝ ํจํด์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง๋๋ค โ ์ด๊ฒ๋ 9๋ฒ RAII์ ๋์์ฑ ๋ฒ์ ์ ๋๋ค.
๋ชจ์๋ฉด์ ๋ต๋ณ
ํ๋ก์ธ์ค์ ์ค๋ ๋๋ ๋ชจ๋ ์คํ ๋จ์์ง๋ง, ์์ ์์ ๋จ์์ธ์ง ์คํ ํ๋ฆ ๋จ์์ธ์ง์์ ๊ฒฐ์ ์ ์ผ๋ก ๊ฐ๋ฆฝ๋๋ค.
ํ๋ก์ธ์ค๋ ์ด์์ฒด์ ๋ก๋ถํฐ ์์์ ํ ๋น๋ฐ๋ ์์ ์ ๋จ์์ ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ(์ฝ๋ยท๋ฐ์ดํฐยทํยท์คํ), ํ์ผ ํธ๋ค, ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋ ๋ฆฝ์ ์ผ๋ก ์์ ํฉ๋๋ค. ํ ํ๋ก์ธ์ค๊ฐ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ์ ๊ทผํ ์ ์๊ณ , ํต์ ํ๋ ค๋ฉด IPC(ํ์ดํยท๊ณต์ ๋ฉ๋ชจ๋ฆฌยท์์ผ ๋ฑ) ๊ฐ์ ๋ช ์์ ๋ฉ์ปค๋์ฆ์ด ํ์ํฉ๋๋ค.
์ค๋ ๋๋ ํ๋ก์ธ์ค ์์์ ์ค์ ๋ก CPU๋ฅผ ์ ์ ํด ์ฝ๋๋ฅผ ์คํํ๋ ํ๋ฆ์ ๋จ์์ ๋๋ค. ํ ํ๋ก์ธ์ค ์์ ์ค๋ ๋๋ค์ ์ฝ๋ยท๋ฐ์ดํฐยทํ์ ๊ณต์ ํ๊ณ ์คํ๊ณผ ๋ ์ง์คํฐ, PC๋ง ๊ฐ์ ๊ฐ์ต๋๋ค. ๊ทธ๋์ ์ค๋ ๋๋ผ๋ฆฌ๋ ์ ์ญ ๋ณ์๋ ํ์ ํ ๋น๋ ๊ฐ์ฒด๋ก ๋ณ๋ ๋น์ฉ ์์ด ํต์ ํ ์ ์์ต๋๋ค.
์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ์์ ์ฐจ์ด๊ฐ ํฝ๋๋ค. ํ๋ก์ธ์ค ์ ํ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋ฐ๊ฟ์ผ ํด์ TLB(Translation Lookaside Buffer)๋ฅผ ๋น์ฐ๊ณ (flush), ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค ๋ ์ง์คํฐ(CR3)๋ฅผ ๊ต์ฒดํฉ๋๋ค. ๊ทธ ์งํ์ L1ยทL2 ์บ์๋ ์ ํ๋ก์ธ์ค ๋ฐ์ดํฐ๊ฐ ์์ด ๋ฏธ์ค๊ฐ ์๋ฐ๋ผ ๋ฐ์ํ๋ โcache coldโ(์บ์ ์ฝ๋) ์ํ๊ฐ ๋ฉ๋๋ค. ์ค๋ ๋ ์ ํ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ์์์ ์ผ์ด๋๋ฏ๋ก TLBยทํ์ด์ง ํ ์ด๋ธ์ ๊ทธ๋๋ก ๋๊ณ ๋ ์ง์คํฐ๋ง ๊ต์ฒดํฉ๋๋ค. ๊ทธ๋์ ์ผ๋ฐ์ ์ผ๋ก ์ค๋ ๋ ์ ํ์ด ํ๋ก์ธ์ค ์ ํ๋ณด๋ค 5~10๋ฐฐ ๋น ๋ฆ ๋๋ค.
ํ์ง๋ง ๊ณต์ ์ ๋๊ฐ๊ฐ ์์ต๋๋ค. ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ๊ฑด๋๋ฆฌ๋ฉด race condition์ด ๋ฐ์ํฉ๋๋ค. count++ ํ ์ค๋ ์ฌ์ค์ loadยทaddยทstore ์ธ ๋จ๊ณ๋ผ ๋ ์ค๋ ๋๊ฐ ์ธํฐ๋ฆฌ๋น๋๋ฉด ๊ฒฐ๊ณผ๊ฐ ๊นจ์ง๋๋ค. ๊ทธ๋์ mutex, atomic, condition variable ๊ฐ์ ๋๊ธฐํ ๋๊ตฌ๊ฐ ํ์ํ๊ณ , ์๋ชป ์ฐ๋ฉด deadlockยทlivelockยทpriority inversion ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ๋ผ์ต๋๋ค. ํ๋ก์ธ์ค๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฒฉ๋ฆฌ๋ผ ์์ด์ ์ด๋ฐ ๋ฌธ์ ๊ฐ ์์ฒ์ ์ผ๋ก ์ ์ต๋๋ค.
๊ทธ๋์ ๋์ ํธ๋ ์ด๋์คํ ๊ด๊ณ์
๋๋ค. ๊ฒฉ๋ฆฌยท์์ ์ฑ์ด ์ค์ํ๋ฉด ๋ฉํฐํ๋ก์ธ์ค(Chrome ํญ ๋ถ๋ฆฌยทPostgres ์์ปค), ๋น ๋ฅธ ํต์ ยท๋ฎ์ ์ค๋ฒํค๋๊ฐ ์ค์ํ๋ฉด ๋ฉํฐ์ค๋ ๋(๊ฒ์ ์์งยท์น ์๋ฒ ์์ปค). ๊ฒ์ ์์ง์ ๋งค ํ๋ ์ 60fps๋ฅผ ๋ง์ถฐ์ผ ํ๋ ํต์ ์ค๋ฒํค๋๊ฐ ํฐ IPC๋ ๋ถ๋ด์ด๊ณ , ๊ทธ๋์ ๊ฒ์ ์ค๋ ๋์ ๋ ๋ ์ค๋ ๋๋ฅผ ๊ฐ์ ํ๋ก์ธ์ค ์์์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ + ๋๊ธฐํ๋ก ์ด์ฉํฉ๋๋ค. ์ธ๋ฆฌ์ผ ์์ง๋ FRunnable, AsyncTask, ParallelFor ๊ฐ์ ์ถ์ํ๋ฅผ ํตํด ์ด ๋ชจ๋ธ์ ๋ฐ๋ฆ
๋๋ค.
ํต์ฌ ๊ฐ๋
| ๋ถ๋ฅ | ํค์๋ | ํ ์ค ์ ์ |
|---|---|---|
| ์ ์ | ํ๋ก์ธ์ค (Process) | ์คํ ์ค์ธ ํ๋ก๊ทธ๋จ. ์์ ์์ ๋จ์ (๋ฉ๋ชจ๋ฆฌยทํธ๋ค ๋ ๋ฆฝ) |
| ย | ์ค๋ ๋ (Thread) | ํ๋ก์ธ์ค ๋ด๋ถ ์คํ ํ๋ฆ ๋จ์. ์ฝ๋ยท๋ฐ์ดํฐยทํ ๊ณต์ |
| ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ | ์ฝ๋ ์์ญ (Text) | ์คํ ๋ช ๋ น์ด. read-only, ์ค๋ ๋ ๊ฐ ๊ณต์ |
| ย | ๋ฐ์ดํฐ ์์ญ (Data/BSS) | ์ ์ญยทstatic ๋ณ์. ์ค๋ ๋ ๊ฐ ๊ณต์ |
| ย | ํ (Heap) | new/malloc๋ก ๋์ ํ ๋น. ์ค๋ ๋ ๊ฐ ๊ณต์ |
| ย | ์คํ (Stack) | ์ง์ญ ๋ณ์ยทํจ์ ํธ์ถ. ์ค๋ ๋๋ง๋ค ๋ ๋ฆฝ |
| ์ ์ด ๋ธ๋ก | PCB (Process Control Block) | OS๊ฐ ํ๋ก์ธ์ค ์ ๋ณด ๊ด๋ฆฌํ๋ ๊ตฌ์กฐ์ฒด (PIDยท๋ฉ๋ชจ๋ฆฌ๋งตยทํธ๋ค ๋ฑ) |
| ย | TCB (Thread Control Block) | ์ค๋ ๋ ์ ๋ณด (TIDยท๋ ์ง์คํฐยท์คํ ํฌ์ธํฐยทPC) |
| ์ปจํ ์คํธ ์ค์์นญ | TLB (Translation Lookaside Buffer) | ๊ฐ์โ๋ฌผ๋ฆฌ ์ฃผ์ ์บ์. ํ๋ก์ธ์ค ์ ํ ์ flush |
| ย | CR3 / ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค | ํ๋ก์ธ์ค ์ ํ ์ ๊ต์ฒด โ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ๊ฐ์ํ |
| ย | PC (Program Counter) | ๋ค์์ ์คํํ ๋ช ๋ น์ด์ ์ฃผ์. ์ค๋ ๋ ์ ํ ์ ๊ต์ฒด โ โ์ด๋๊น์ง ์คํํ๋์งโ |
| ย | SP (Stack Pointer) | ํ์ฌ ์คํ์ ์ต์๋จ ์ฃผ์. ์ค๋ ๋๋ง๋ค ์๊ธฐ ์คํ์ ๊ฐ๋ฆฌํด |
| ย | ๋ฒ์ฉ ๋ ์ง์คํฐ (General Purpose Register) | x86_64 ๊ธฐ์ค raxยทrbxยทrcxยทrdxยทrsiยทrdiยทr8~r15 ๋ฑ. ์ฐ์ฐ ์ค์ธ ์์ ๊ฐยทํจ์ ์ธ์ยท๋ฆฌํด๊ฐ ์ ์ฅ |
| ย | ๋ ์ง์คํฐ ์ปจํ ์คํธ | ์ ์ (PCยทSPยท๋ฒ์ฉ)์ ๋ฌถ์ด ๋ถ๋ฅด๋ ๋ง. TCB์ ์ ์ฅ๋๋ค๊ฐ ๋ณต์ โ ์ค๋ ๋ ์ ํ์ ๋ณธ์ฒด |
| ํต์ | IPC (Inter-Process Communication) | ํ๋ก์ธ์ค ๊ฐ ํต์ . ํ์ดํยท๊ณต์ ๋ฉ๋ชจ๋ฆฌยท๋ฉ์์ง ํยท์์ผ |
| ย | ๊ณต์ ๋ฉ๋ชจ๋ฆฌ / ์ ์ญ ๋ณ์ | ์ค๋ ๋ ๊ฐ ํต์ ์ ๊ธฐ๋ณธ โ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ด๋ผ ๊ทธ๋ฅ ์ ๊ทผ |
| ๋๊ธฐํ | race condition | ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ฐ์ ๋ฐ์ดํฐ์ ๋์ ์ ๊ทผํด ๊ฒฐ๊ณผ๊ฐ ๋น๊ฒฐ์ ์ |
| ย | ์๊ณ ๊ตฌ์ญ (Critical Section) | ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์คํํด์ผ ํ๋ ์ฝ๋ ๊ตฌ๊ฐ |
| ย | mutex (mutual exclusion) | ์ํธ ๋ฐฐ์ ๋ฝ. ํ ์ค๋ ๋๋ง ์์ ์ ์ |
| ย | deadlock | ๋ ์ค๋ ๋๊ฐ ์๋ก์ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ์์ํ ๋ฉ์ถค (4๊ฐ์ง ์กฐ๊ฑด) |
| ย | atomic | CPU ๋ช ๋ น์ด๋ก ๋ณด์ฅ๋๋ ์์์ ์ฐ์ฐ (lock-free) |
| ๋ชจ๋ธ | ์ฌ์ฉ์ ์ค๋ ๋ | ์ฌ์ฉ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ด๋ฆฌ. ๋น ๋ฅด์ง๋ง ์์คํ ์ฝ ์ฐจ๋จ์ ์ทจ์ฝ |
| ย | ์ปค๋ ์ค๋ ๋ | OS ์ง์ ๊ด๋ฆฌ. ์์คํ ์ฝ ์์ ๋ก์ |
| ย | 1:1 ๋ชจ๋ธ | ์ ์ 1 โ ์ปค๋ 1. WindowsยทLinux pthread |
| ย | N:1 ๋ชจ๋ธ | ์ ์ N โ ์ปค๋ 1. ๊ฐ๋ฒผ์ฐ๋ ํ ์์คํ ์ฝ์ ์ ๋ถ ์ฐจ๋จ |
| ย | M:N ๋ชจ๋ธ | ์ ์ M โ ์ปค๋ N. Go ๊ณ ๋ฃจํด ๋ฑ |
| C++ API | std::thread | C++11 ํ์ค ์ค๋ ๋. 1:1 ๋ชจ๋ธ (OS ์ค๋ ๋ ๋ํ) |
| ย | std::mutex | ์ํธ ๋ฐฐ์ ๋ฝ. ๋ณต์ฌยท์ด๋ ๋ถ๊ฐ (Community 23) |
| ย | std::lock_guard | RAII ๋ฝ. ์์ฑ ์ lock, ์๋ฉธ ์ unlock |
| ย | std::scoped_lock (C++17) | ์ฌ๋ฌ mutex ๋์ ๋ฝ. ๋ฐ๋๋ฝ ํํผ |
| ย | std::async/std::future | ๋น๋๊ธฐ ์์ ์คํ + ๊ฒฐ๊ณผ ๊ธฐ๋ค๋ฆผ |
| ย | std::atomic<T> | ์์์ ๋ณ์. ๋ฝ ์์ด ์์ ํ read-modify-write |
| ์ธ๋ฆฌ์ผ | ๊ฒ์ ์ค๋ ๋ (Game Thread) | ๋ฉ์ธ ์ค๋ ๋. AActorยทTickยทUI ์ฒ๋ฆฌ |
| ย | ๋ ๋ ์ค๋ ๋ (Render Thread) | ๊ฒ์ ์ค๋ ๋์ ๋ช ๋ น์ ๋ฐ์ GPU ๋ช ๋ น์ด ์์ฑ |
| ย | FRunnable / FRunnableThread | ์ธ๋ฆฌ์ผ ์์ปค ์ค๋ ๋ ์ถ์ํ |
| ย | AsyncTask / ParallelFor | ์งง์ ์์ ํ ๋์คํจ์น / ๋ณ๋ ฌ ๋ฃจํ |
| ย | FCriticalSection / FScopeLock | mutex / RAII ๋ฝ (Community 7) |
| ์ฌ๋ก | Chrome ๋ฉํฐํ๋ก์ธ์ค | ํญ๋ง๋ค ํ๋ก์ธ์ค โ ๊ฒฉ๋ฆฌยท๋ณด์ |
| ย | ๊ฒ์ ์์ง ๋ฉํฐ์ค๋ ๋ | ๊ฐ์ ํ๋ก์ธ์ค์ ๊ฒ์/๋ ๋ ์ค๋ ๋ โ 60fps ์ํด IPC ํํผ |
๋ชฉ์ฐจ
- ํต์ฌ ์์ฝ ์นด๋
- ํ ์ค ์ ์ โ ํ๋ก์ธ์ค์ ์ค๋ ๋
- ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ๋น๊ต โ ์ฝ๋/๋ฐ์ดํฐ/ํ/์คํ๊ณผ PCB/TCB
- ์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ โ ์ ์ค๋ ๋๊ฐ ๋น ๋ฅธ๊ฐ
- ํต์ ๋ฐฉ์ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ
- ๋๊ธฐํ ๋ฌธ์ โ race condition / mutex / deadlock
- ๋ฉํฐํ๋ก์ธ์ค vs ๋ฉํฐ์ค๋ ๋ โ ์ธ์ ๋ฌด์์ ์ฐ๋
- ์ฌ์ฉ์ ์ค๋ ๋ vs ์ปค๋ ์ค๋ ๋ โ 1:1 / N:1 / M:N ๋ชจ๋ธ
- C++ ์ฝ๋ ์์ โ std::thread / mutex / async / atomic
- ์ธ๋ฆฌ์ผ์์์ ์ค๋ ๋ โ ๊ฒ์ ์ค๋ ๋ / ๋ ๋ ์ค๋ ๋ / FRunnable
- ๊ผฌ๋ฆฌ์ง๋ฌธ ์์ ๊ฒฝ๋ก
1. ํต์ฌ ์์ฝ ์นด๋
30์ด ๋ต๋ณ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ํ๋ก์ธ์ค = ์คํ ์ค์ธ ํ๋ก๊ทธ๋จ. ์์ ์์ ๋จ์.
๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ(์ฝ๋ยท๋ฐ์ดํฐยทํยท์คํ)ยทํธ๋คยท๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋
๋ฆฝ์ ์ผ๋ก ๊ฐ์ง.
ํต์ ์ IPC (ํ์ดํยท๊ณต์ ๋ฉ๋ชจ๋ฆฌยท์์ผ ๋ฑ ๋ช
์์ ๋ฉ์ปค๋์ฆ).
์ค๋ ๋ = ํ๋ก์ธ์ค ๋ด๋ถ์ ์คํ ํ๋ฆ. CPU ์ ์ ๋จ์.
์ฝ๋ยท๋ฐ์ดํฐยทํ์ ๊ณต์ , ์คํยท๋ ์ง์คํฐยทPC๋ง ๊ฐ์.
ํต์ ์ ์ ์ญ ๋ณ์ยทํ ๊ฐ์ฒด๋ก ์ฆ์ ๊ฐ๋ฅ (๊ทธ๋ฌ๋ ๋๊ธฐํ ํ์).
์ฐจ์ด 3๊ฐ์ง:
โ ์์ ์์ โ ํ๋ก์ธ์ค๋ ๋
๋ฆฝ, ์ค๋ ๋๋ ๊ณต์
โก ์ปจํ
์คํธ ์ค์์นญ ๋น์ฉ โ ์ค๋ ๋๊ฐ 5~10๋ฐฐ ๋น ๋ฆ (TLB flush ์์)
โข ํต์ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ (์๋์ ์์ ์ฑ ํธ๋ ์ด๋์คํ)
์ ํ ๊ธฐ์ค:
๊ฒฉ๋ฆฌยท์์ ์ฑ โ ๋ฉํฐํ๋ก์ธ์ค (Chrome ํญ, Postgres ์์ปค)
์๋ยทํต์ โ ๋ฉํฐ์ค๋ ๋ (๊ฒ์ ์์ง, ์น ์๋ฒ ์์ปค)
๊ฒ์ ์์ง: ๋งค ํ๋ ์ 60fps โ IPC ๋ถ๋ด โ ๋ฉํฐ์ค๋ ๋ (๊ฒ์/๋ ๋ ์ค๋ ๋)
๊ผฌ๋ฆฌ์ง๋ฌธ ์ฐ๊ฒฐ ๋งต
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ํ๋ก์ธ์ค vs ์ค๋ ๋
โโโ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ โ ์ฝ๋/๋ฐ์ดํฐ/ํ์ ๊ณต์ , ์คํ์ ๋
๋ฆฝ
โ โโโ PCB vs TCB (TCB๊ฐ ํจ์ฌ ๊ฐ๋ฒผ์)
โโโ ์ปจํ
์คํธ ์ค์์นญ ๋น์ฉ โ ์ ์ค๋ ๋๊ฐ ๋น ๋ฅธ๊ฐ?
โ โโโ TLB flush ํํผ
โ โโโ ์บ์ locality ์ ์ง
โโโ ํต์ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ
โ โโโ ํ์ดํยท๊ณต์ ๋ฉ๋ชจ๋ฆฌยท์์ผยท๋ฉ์์ง ํ
โ โโโ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ = ์ํ โ mutex ํ์
โโโ ๋๊ธฐํ โ race condition / mutex / deadlock
โ โโโ lock_guard / scoped_lock (RAII) โ 9๋ฒ RAII ํ๊ท
โ โโโ atomic โ lock-free (shared_ptr ์ ์ด ๋ธ๋ก) โ 11๋ฒ ํ๊ท
โ โโโ deadlock 4์กฐ๊ฑด + ํํผ ํจํด
โโโ ๋ชจ๋ธ โ 1:1 / N:1 / M:N
โ โโโ std::thread (1:1)
โ โโโ Go goroutine (M:N)
โโโ ์ฌ๋ก
โ โโโ Chrome (๋ฉํฐํ๋ก์ธ์ค โ ๋ณด์ยท๊ฒฉ๋ฆฌ)
โ โโโ Postgres (๋ฉํฐํ๋ก์ธ์ค โ ์์ ์ฑ)
โ โโโ Apache vs Nginx (์ค๋ ๋ vs ์ด๋ฒคํธ)
โ โโโ ๊ฒ์ ์์ง (๋ฉํฐ์ค๋ ๋ โ 60fps)
โโโ ์ธ๋ฆฌ์ผ โ ๊ฒ์ ์ค๋ ๋ / ๋ ๋ ์ค๋ ๋ / FRunnable / AsyncTask / FScopeLock
2. ํ ์ค ์ ์ โ ํ๋ก์ธ์ค์ ์ค๋ ๋
ํต์ฌ ํ ๋ฌธ์ฅ
ํ๋ก์ธ์ค๋ ์์์ ์์ ํ๋ ๋จ์๊ณ , ์ค๋ ๋๋ ๊ทธ ์์ ์์์ ์คํ๋๋ ํ๋ฆ์ ๋๋ค.
ํ๋ก์ธ์ค (Process)
โ์คํ ์ค์ธ ํ๋ก๊ทธ๋จ์ ์ธ์คํด์ค.โ ๋์คํฌ์ ์๋ ์คํ ํ์ผ์ด ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋์ด OS๋ก๋ถํฐ ์์์ ํ ๋น๋ฐ์ ์ํ.
1
2
3
4
5
6
7
8
ํ๋ก์ธ์ค๊ฐ ๊ฐ์ง ๊ฒ:
โโ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ (์ฝ๋ยท๋ฐ์ดํฐยทํยท์คํ)
โโ ํ์ผ ํธ๋ค / ์์ผ ๋์คํฌ๋ฆฝํฐ
โโ ํ๊ฒฝ ๋ณ์
โโ PID (ํ๋ก์ธ์ค ์๋ณ์)
โโ ์์ ํ๋ก์ธ์ค ์ ๋ณด, ๋ถ๋ชจ PID
โโ CPU ๋ ์ง์คํฐ ์ํ (์ค๋ ๋ 1๊ฐ ์ด์)
โโ ํ์ด์ง ํ
์ด๋ธ (๊ฐ์โ๋ฌผ๋ฆฌ ์ฃผ์ ๋งคํ)
โ ํ๋ก์ธ์ค๋ ๊ฒฉ๋ฆฌ(isolation)๊ฐ ๊ธฐ๋ณธ์ ๋๋ค. A ํ๋ก์ธ์ค๊ฐ B ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ์ฝ์ผ๋ ค ํ๋ฉด OS๊ฐ segfault๋ก ์ฐจ๋จํฉ๋๋ค.
์ค๋ ๋ (Thread)
โํ๋ก์ธ์ค ๋ด๋ถ์์ CPU๋ฅผ ์ ์ ํด ์ฝ๋๋ฅผ ์คํํ๋ ํ๋ฆ.โ ํ ํ๋ก์ธ์ค ์์ ์ฌ๋ฌ ๊ฐ ์กด์ฌํ ์ ์๊ณ , ๊ฐ๊ฐ์ด ๋ ๋ฆฝ์ ์ผ๋ก ์ค์ผ์ค๋ง๋ฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
์ค๋ ๋๊ฐ ๊ฐ์ง ๊ฒ (์๊ธฐ๋ง์):
โโ ์คํ
โโ ๋ ์ง์คํฐ ์ปจํ
์คํธ (PC, SP, ๋ฒ์ฉ ๋ ์ง์คํฐ)
โโ TID (์ค๋ ๋ ์๋ณ์)
โโ ์๊ทธ๋ ๋ง์คํฌ
โโ TLS (Thread Local Storage)
์ค๋ ๋๊ฐ ๊ณต์ ํ๋ ๊ฒ (ํ๋ก์ธ์ค ์์ ๋ค๋ฅธ ์ค๋ ๋์):
โโ ์ฝ๋ ์์ญ (Text)
โโ ์ ์ญยทstatic ๋ฐ์ดํฐ (Data/BSS)
โโ ํ
โโ ํ์ผ ํธ๋ค
โโ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ์ ์ฒด
โ โ์ค๋ ๋ = light-weight process(LWP)โ๋ผ๊ณ ๋ ๋ถ๋ฅด๋ ์ด์ . ์ ํ๋ก์ธ์ค ๋ง๋๋ ๊ฒ๋ณด๋ค ์ ์ค๋ ๋ ๋ง๋๋ ๊ฒ ํจ์ฌ ๊ฐ๋ณ์ต๋๋ค.
๋น์ ๋ก
1
2
3
4
5
6
7
8
9
ํ๋ก์ธ์ค = ํ ์ฑ์ ์ง
โโ ์๊ธฐ ๋ง๋น, ์๊ธฐ ๋ถ์, ์๊ธฐ ์์ค (๋
๋ฆฝ ์์)
โโ ๋ค๋ฅธ ์ง๊ณผ ํต์ ํ๋ ค๋ฉด ์ฐํธยท์ ํ (IPC)
์ค๋ ๋ = ๊ฐ์ ์ง ์์ ์ฌ๋ ๊ฐ์กฑ ๊ตฌ์ฑ์
โโ ๋ถ์ยท๊ฑฐ์คยทํ์ฅ์ค์ ๊ณต์ (์ฝ๋ยท๋ฐ์ดํฐยทํ)
โโ ์๊ธฐ ์นจ๋ยท์ท์ฅ์ ๋
๋ฆฝ (์คํยท๋ ์ง์คํฐ)
โโ ํ ํ์ฅ์ค์ ์ฌ๋ฌ ๋ช
์ด ๋์์ ๋ค์ด๊ฐ๋ฉด ์ถฉ๋ (race condition)
โ ๋ฌธ์ ์ ๊ธ ํ์ (mutex)
3. ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ๋น๊ต โ ์ฝ๋/๋ฐ์ดํฐ/ํ/์คํ๊ณผ PCB/TCB
๋ฉ๋ชจ๋ฆฌ ์์ญ 4๊ตฌ์ญ ๋ณต๊ธฐ (01_runtime, 03_new_vs_malloc ํ๊ท)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
๋์ ์ฃผ์
โโโโโโโโโโโโโโโโโโโ
โ ์คํ (Stack) โ โ ์ง์ญ ๋ณ์, ํจ์ ํธ์ถ ํ๋ ์. ์ค๋ ๋๋ง๋ค ๋
๋ฆฝ.
โ โ โ
โโโโโโโโโโโโโโโโโโโค
โ โ
โ ํ (Heap) โ โ new/malloc. ์ค๋ ๋ ๊ฐ ๊ณต์ . โ
๋๊ธฐํ ํ์
โ โ โ
โโโโโโโโโโโโโโโโโโโค
โ Data / BSS โ โ ์ ์ญยทstatic ๋ณ์. ์ค๋ ๋ ๊ฐ ๊ณต์ . โ
๋๊ธฐํ ํ์
โโโโโโโโโโโโโโโโโโโค
โ Code (Text) โ โ ์คํ ๋ช
๋ น์ด. read-only. ๊ณต์ (์์ฐ์ค๋ฌ์)
โโโโโโโโโโโโโโโโโโโ
๋ฎ์ ์ฃผ์
๋จ์ผ ์ค๋ ๋ vs ๋ฉํฐ์ค๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
๋จ์ผ ์ค๋ ๋ ํ๋ก์ธ์ค
โโโโโโโโโโโโโโโโโโโโโโโ
โ Stack (1๊ฐ) โ
โ โ โ
โ โ
โ โ โ
โ Heap โ
โ Data โ
โ Code โ
โโโโโโโโโโโโโโโโโโโโโโโ
๋ฉํฐ์ค๋ ๋ ํ๋ก์ธ์ค (์ค๋ ๋ 3๊ฐ)
โโโโโโโโโโโโโโโโโโโโโโโ
โ Stack 1 โ Stack 2 โ โ ๊ฐ ์ค๋ ๋์ ๋
๋ฆฝ ์คํ
โ โ โ โ โ
โโโโโโโโโโโผโโโโโโโโโโโโค
โ Stack 3 โ โ
โ โ โ โ
โ โ โ
โ โ
๊ณต์ ์์ญ โ
โ
โ โ โ
โ Heap (๊ณต์ ) โ โ ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ๊ฐ์ฒด์ ์ ๊ทผ ๊ฐ๋ฅ
โ Data (๊ณต์ ) โ โ ์ ์ญ ๋ณ์๋ ๊ณต์
โ Code (๊ณต์ ) โ
โโโโโโโโโโโโโโโโโโโโโโโ
โ ์ค๋ ๋ ๊ฐ ํต์ ์ ์์ฐ์ค๋ฝ๋ค(๊ฐ์ ํยท๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฅ ์ฝ๊ณ ์ฐ๋ฉด ๋จ). ๋จ, ๊ทธ ์์ฐ์ค๋ฌ์์ด race condition์ ์์ธ์ด๊ธฐ๋ ํฉ๋๋ค.
PCB vs TCB
| ํญ๋ชฉ | PCB (Process Control Block) | TCB (Thread Control Block) |
|---|---|---|
| ์ ์ฅ ์์น | OS ์ปค๋ (ํ๋ก์ธ์ค ํ ์ด๋ธ) | OS ์ปค๋ (์ค๋ ๋ ํ ์ด๋ธ) |
| ์๋ณ์ | PID | TID |
| ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด | ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค, ๋ฉ๋ชจ๋ฆฌ๋งต, ์ฝ๋/๋ฐ์ดํฐ/ํ ์์ญ ์ ๋ณด | (์์ โ ํ๋ก์ธ์ค์ PCB ์ฐธ์กฐ) |
| CPU ์ปจํ ์คํธ | (์ค๋ ๋๋ค์ ์ปจํ ์คํธ ๋ชจ์) | PC, SP, ๋ฒ์ฉ ๋ ์ง์คํฐ |
| ํธ๋คยท์์ | ํ์ผ ๋์คํฌ๋ฆฝํฐ, ์์ผ, ํ๊ฒฝ ๋ณ์ | (์์ โ ํ๋ก์ธ์ค์ PCB ๊ณต์ ) |
| ๋ถ๋ชจ/์์ | ๋ถ๋ชจ PID, ์์ PID ๋ฆฌ์คํธ | (ํด๋น ์์) |
| ์ค์ผ์ค๋ง ์ ๋ณด | ์ฐ์ ์์, ์ํ(Ready/Running/Wait) | ์ค๋ ๋๋ณ ์ฐ์ ์์ยท์ํ |
| ํฌ๊ธฐ | ํผ (์ KB) | ์์ (์๋ฐฑ ๋ฐ์ดํธ) |
โ TCB๊ฐ ํจ์ฌ ์๊ณ ๊ฐ๋ฒผ์ด ๊ฒ ์ค๋ ๋ ์์ฑยท์ ํ ๋น์ฉ์ด ๋ฎ์ ์ง์ ์ ์ด์ ์ ๋๋ค.
Linux์ task_struct (์ฐธ๊ณ )
Linux๋ ์ฌ์ค ํ๋ก์ธ์ค์ ์ค๋ ๋๋ฅผ ๊ฐ์
task_struct๋ก ํํํฉ๋๋ค. ๋จ์งclone()ํธ์ถ ์ ์ด๋ค ์์์ ๊ณต์ ํ ์ง ํ๋๊ทธ๋ก ์ง์ ํด์, ๋ชจ๋ ๊ณต์ ํ๋ฉด ์ค๋ ๋์ฒ๋ผ, ์๋ฌด๊ฒ๋ ๊ณต์ ์ ํ๋ฉด ํ๋ก์ธ์ค์ฒ๋ผ ๋์ํ๊ฒ ๋ง๋ญ๋๋ค.
1
2
3
4
5
// Linux clone() ํ๋๊ทธ (์์ฝ)
clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD, ...)
// โ ๋ฉ๋ชจ๋ฆฌ ๊ณต์ โ โ ํ์ผ์์คํ
โ โ FD ๊ณต์ โ โ ์๊ทธ๋ โ โ ์ค๋ ๋๊ทธ๋ฃน โ
// โ ์ ํ๋๊ทธ ๋ค ์ผ๋ฉด "์ค๋ ๋ ์์ฑ" (pthread_create ๋ด๋ถ ํธ์ถ)
// โ ๋ค ๋๋ฉด fork() (๋ณ๊ฐ ํ๋ก์ธ์ค)
โ โํ๋ก์ธ์ค/์ค๋ ๋๋ OS ์ถ์ํ์ ์ ๋์ผ ๋ฟ ๋ณธ์ง์ ๊ฐ์ task๋คโ๋ผ๋ ๊ด์ .
4. ์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ โ ์ ์ค๋ ๋๊ฐ ๋น ๋ฅธ๊ฐ
ํต์ฌ ํ ๋ฌธ์ฅ
ํ๋ก์ธ์ค ์ ํ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๊ฐ์ํ๋ ๋น์ฉ(TLB flush + ํ์ด์ง ํ ์ด๋ธ ๊ต์ฒด + ์บ์ cold start)์ด ์ถ๊ฐ๋ก ๋ค๊ณ , ์ค๋ ๋ ์ ํ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ์์ด๋ผ ๋ ์ง์คํฐ๋ง ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค.
์ปจํ ์คํธ ์ค์์นญ์ด๋
1
2
3
4
5
์คํ ํ๋ฆ A์์ B๋ก CPU๋ฅผ ๋๊ธฐ๋ ๊ณผ์ :
โ A์ CPU ๋ ์ง์คํฐ(PC, SP, ๋ฒ์ฉ)๋ฅผ A์ PCB/TCB์ ์ ์ฅ
โก OS ์ค์ผ์ค๋ฌ๊ฐ B๋ฅผ ์ ํ
โข B์ PCB/TCB์์ ๋ ์ง์คํฐ๋ฅผ ๋ณต์ โ CPU์ ๋ก๋
โฃ B ์คํ ์ฌ๊ฐ
ํ๋ก์ธ์ค ์ ํ ์ถ๊ฐ ๋น์ฉ
1
2
3
4
5
6
7
8
9
ํ๋ก์ธ์ค A โ B ์ ํ:
[๊ณตํต]
โ A ๋ ์ง์คํฐ ์ ์ฅ
โก B ๋ ์ง์คํฐ ๋ณต์
[ํ๋ก์ธ์ค ์ ํ๋ง ์ถ๊ฐ]
โข ํ์ด์ง ํ
์ด๋ธ ๋ฒ ์ด์ค ๋ ์ง์คํฐ(x86: CR3) ๊ต์ฒด
โฃ TLB flush (๋๋ ๋ถ๋ถ ๋ฌดํจํ) โ
ํฐ ๋น์ฉ
โค ์งํ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ = TLB miss โ ํ์ด์ง ํ
์ด๋ธ ์ํฌ
โฅ L1ยทL2 ์บ์๋ ์ฐจ๊ฐ์ (cache cold) โ
ํฐ ๋น์ฉ
์ค๋ ๋ ์ ํ (๊ฐ์ ํ๋ก์ธ์ค ์)
1
2
3
4
5
6
์ค๋ ๋ X โ Y ์ ํ (๊ฐ์ ํ๋ก์ธ์ค P ์):
โ X ๋ ์ง์คํฐ ์ ์ฅ
โก Y ๋ ์ง์คํฐ ๋ณต์
โ ๋!
TLBยทํ์ด์ง ํ
์ด๋ธยท์บ์ ๋ชจ๋ ๊ทธ๋๋ก
(์ฝ๋ยท๋ฐ์ดํฐยทํ์ ๊ณต์ ๋ผ ์บ์ ๋ผ์ธ์ด ์๋ฏธ ์๊ฒ ๋จ์์์)
๋น์ฉ ์ฐจ์ด (๋๋ต์ ์ธ ์์น)
| ์์ | ์๊ฐ (์ฐธ๊ณ ์น) |
|---|---|
| ํจ์ ํธ์ถ | ~1 ns |
| L1 ์บ์ ์ ๊ทผ | ~1 ns |
| L2 ์บ์ ์ ๊ทผ | ~5 ns |
| ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ | ~100 ns |
| ์์คํ ์ฝ | ~500~1000 ns |
| ์ค๋ ๋ ์ปจํ ์คํธ ์ค์์นญ | ~1~10 ฮผs |
| ํ๋ก์ธ์ค ์ปจํ ์คํธ ์ค์์นญ | ~5~50 ฮผs (TLBยท์บ์ ์ํฅ ํฌํจ ์ ๋ ํผ) |
โ ๋จ์ ๋ ์ง์คํฐ ๊ตํ๋ง ๋ณด๋ฉด ๋ ๋ค ๋ง์ดํฌ๋ก์ด ๋จ์์ง๋ง, TLBยท์บ์ ํจ๊ณผ๊น์ง ํฌํจํ๋ฉด ํ๋ก์ธ์ค ์ ํ์ ์์ญ ฮผs๊น์ง ๋์ด๋ ์ ์์ต๋๋ค. ๊ฒ์ ์์ง์ฒ๋ผ 16.6ms(60fps) ์์ ์ ๋ถ ์ฒ๋ฆฌํด์ผ ํ๋ ํ๊ฒฝ์์ ์ด ์ฐจ์ด๊ฐ ๊ฒฐ์ ์ ์ ๋๋ค.
TLB์ ํ์ด์ง ํ ์ด๋ธ (๊ฐ๋จํ)
1
2
3
4
5
6
7
๊ฐ์ ์ฃผ์ โ ๋ฌผ๋ฆฌ ์ฃผ์ ๋ณํ ํ๋ฆ:
โ CPU๊ฐ ๊ฐ์ ์ฃผ์ ๋ฐํ
โก TLB์์ ๋งคํ ๊ฒ์ (์บ์ hit์ด๋ฉด ์ฆ์)
โข TLB miss โ ํ์ด์ง ํ
์ด๋ธ ์ํฌ (4๋จ๊ณ โ x86_64) โ ์์ญ ns
โฃ ๊ฒฐ๊ณผ๋ฅผ TLB์ ์ ์ฌ
TLB flush: ์ ์บ์๋ฅผ ํต์งธ๋ก ๋ฌดํจํ โ ํ๋์ ๋งค๋ฒ page walk
โ ๊ทธ๋์ ํ๋ก์ธ์ค ์ ํ ์งํ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ ์๊ธฐ(์๋ฐ์ )๊ฐ ์ ๊น ์์ต๋๋ค.
๋น๊ต ํ
| ํญ๋ชฉ | ํ๋ก์ธ์ค ์ ํ | ์ค๋ ๋ ์ ํ (๊ฐ์ ํ๋ก์ธ์ค) |
|---|---|---|
| ๋ ์ง์คํฐ ์ ์ฅ/๋ณต์ | โ | โ |
| ํ์ด์ง ํ ์ด๋ธ ๊ต์ฒด | โ (CR3) | โ |
| TLB flush | โ ๋๋ ๋ถ๋ถ ๋ฌดํจํ | โ |
| L1ยทL2 ์บ์ ์ํฅ | ํผ (cold) | ์์ (warm ์ ์ง) |
| ๋น์ฉ (์ค์ธก ๋๋ต) | ~5~50 ฮผs | ~1~10 ฮผs |
| ํต์ ๋น์ฉ๋ | IPC (์ถ๊ฐ) | ๊ณต์ ๋ฉ๋ชจ๋ฆฌ (์ถ๊ฐ ๋น์ฉ 0) |
5. ํต์ ๋ฐฉ์ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ
ํต์ฌ ํ ๋ฌธ์ฅ
ํ๋ก์ธ์ค๋ผ๋ฆฌ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฒฉ๋ฆฌ๋ผ ์์ด ๋ช ์์ IPC ๋ฉ์ปค๋์ฆ์ด ํ์ํ๊ณ , ์ค๋ ๋๋ผ๋ฆฌ๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ณด๊ณ ์์ด ๊ทธ๋ฅ ๋ณ์์ ์ ๊ทผํ๋ฉด ๋ฉ๋๋ค(๋์ ๋๊ธฐํ ํ์).
IPC (Inter-Process Communication) ์ข ๋ฅ
| ๋ฐฉ์ | ์ค๋ช | ์๋ | ์ฉ๋ |
|---|---|---|---|
| ํ์ดํ (anonymous pipe) | ๋ถ๋ชจ-์์ ๋จ๋ฐฉํฅ ๋ฐ์ดํธ ์คํธ๋ฆผ | ๋ณดํต | ์ ธ | ๊ฐ์ ๋จ์ ์ฐ๊ฒฐ |
| named pipe (FIFO) | ํ์ผ ์์คํ ์ ์ด๋ฆ ๊ฐ์ง ํ์ดํ | ๋ณดํต | ๋ฌด๊ดํ ํ๋ก์ธ์ค ๊ฐ |
| ๊ณต์ ๋ฉ๋ชจ๋ฆฌ (shared memory) | ๊ฐ์ ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋งคํ | ๋น ๋ฆ (๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์๋) | DBยท๊ณ ์ฑ๋ฅ IPC |
| ๋ฉ์์ง ํ (POSIX/SysV) | ์ปค๋์ด ๊ด๋ฆฌํ๋ ๋ฉ์์ง ๋ฒํผ | ๋ณดํต | ๋น๋๊ธฐ ๋ฉ์์ง |
| ์ธ๋งํฌ์ด (semaphore) | IPC์ฉ ๋๊ธฐํ (๊ฐ ๊ธฐ๋ฐ) | ๋น ๋ฆ | ๋ค๋ฅธ IPC์ ๋ณํ |
| ์๊ทธ๋ (signal) | ๋น๋๊ธฐ ์๋ฆผ (SIGINT ๋ฑ) | ๋น ๋ฆ | ์ข ๋ฃยท์ธํฐ๋ฝํธ ์๋ฆผ |
| ์์ผ (Unix domain / TCP) | ์๋ฐฉํฅ ์คํธ๋ฆผ. ๋คํธ์ํฌ๋ OK | ๋๋ฆผ~๋ณดํต | ๋ถ๋ฆฌ๋ ํ๋ก์ธ์คยท๋ค๋ฅธ ๋จธ์ |
| ๋ฉ๋ชจ๋ฆฌ ๋งคํ (mmap) | ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ๋ก ๋งคํ | ๋น ๋ฆ | ํ์ผ ๊ณต์ ยท๊ณต์ ๋ฉ๋ชจ๋ฆฌ |
์ค๋ ๋ ๊ฐ โํต์ โ
1
2
3
4
5
6
7
8
9
10
11
12
// ์ ์ญ ๋ณ์ โ ๊ฐ์ฅ ๋จ์ํ ๊ณต์
int counter = 0;
void Worker() {
counter++; // ๊ทธ๋ฅ ์ ๊ทผ. ๋ณ๋ IPC ๋ฉ์ปค๋์ฆ ๋ถํ์.
}
// ํ ๊ฐ์ฒด ๊ณต์
auto data = std::make_shared<std::vector<int>>();
std::thread t1([data]{ data->push_back(1); });
std::thread t2([data]{ data->push_back(2); });
// ๊ฐ์ vector๋ฅผ ๋ ์ค๋ ๋๊ฐ ํจ๊ป ๋ด
โ ์ด๊ฒ ๋น ๋ฅด๊ณ ์์ฐ์ค๋ฌ์ด๋ฐ, ๊ทธ๋์ race condition ์ํ์ด ๋ฐ๋ผ์ต๋๋ค.
๊ณต์ ๋ฉ๋ชจ๋ฆฌ IPC vs ์ค๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต์ โ ๋น์ทํ์ง๋ง ๋ค๋ฆ
1
2
3
4
5
6
๊ณต์ ๋ฉ๋ชจ๋ฆฌ IPC: ๋ ํ๋ก์ธ์ค๊ฐ ๋ช
์์ ์ผ๋ก ๊ฐ์ ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ์๊ธฐ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋งคํ
(shmget/shmat ๋๋ mmap ์ฌ์ฉ)
โ ๊ฒฉ๋ฆฌ๋ ๊นจ์ง์ง๋ง, ๋ช
์์ ์ค์ ์ด ํ์
์ค๋ ๋ ๊ณต์ : ํ๋ก์ธ์ค ์์ ๋ชจ๋ ์ค๋ ๋๊ฐ ์๋์ผ๋ก ๊ฐ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋ณธ๋ค
โ ๋ณ๋ ์ค์ 0
๋น์ฉยท์์ ์ฑ ํธ๋ ์ด๋์คํ
| ํต์ ๋ฐฉ์ | ์๋ | ๊ฒฉ๋ฆฌ | ๋๊ธฐํ ํ์ |
|---|---|---|---|
| ์์ผ (TCP) | ๋๋ฆผ | ๊ฐํจ (๋ค๋ฅธ ๋จธ์ ๋ OK) | ํ๋กํ ์ฝ ์์ฒด๋ก |
| ํ์ดํยท๋ฉ์์ง ํ | ๋ณดํต | ๊ฐํจ | ์ปค๋์ด ๋ณด์ฅ |
| ๊ณต์ ๋ฉ๋ชจ๋ฆฌ IPC | ๋น ๋ฆ | ์ฝํจ (๋ช ์์ ๋งคํ) | ์๋ (mutex ๋ฑ) |
| ์ค๋ ๋ ๊ณต์ ๋ณ์ | ๊ฐ์ฅ ๋น ๋ฆ | ์์ | ์๋ (๋ฐ๋์) |
โ โ๊ฒฉ๋ฆฌ๋ฅผ ํฌ๊ธฐํ ์๋ก ๋น ๋ฅด๋คโ๋ ์ผ๊ด๋ ํธ๋ ์ด๋์คํ. ๊ฒ์ ์์ง์ฒ๋ผ ๋งค ํ๋ ์ ์๋ง ๊ฐ ๊ฐ์ฒด๋ฅผ ๋ค๋ค์ผ ํ๋ ํ๊ฒฝ์ ๊ฒฉ๋ฆฌ๋ฅผ ํฌ๊ธฐํ๊ณ ์ค๋ ๋ ๊ณต์ ๋ฅผ ์ ํํ ์๋ฐ์ ์์ต๋๋ค.
6. ๋๊ธฐํ ๋ฌธ์ โ race condition / mutex / deadlock
ํต์ฌ ํ ๋ฌธ์ฅ
๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋ ๊ฐ ์ด์์ ์ค๋ ๋๊ฐ non-atomicํ ์ฐ์ฐ์ผ๋ก ๋์ ์ ๊ทผํ๋ฉด race condition์ด ๋ฐ์ํฉ๋๋ค. ํด๊ฒฐ์ฑ ์ ์๊ณ ๊ตฌ์ญ์ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์คํํ๋๋ก mutex ๋ฑ์ผ๋ก ๋ณดํธํ๋ ๊ฒ์ด๊ณ , ๊ทธ ๊ณผ์ ์์ deadlock ๊ฐ์ ์๋ก์ด ๋ฌธ์ ๊ฐ ๋ฐ๋ผ์ต๋๋ค.
Race Condition ์๊ฐํ
1
2
int counter = 0; // ์ ์ญ ๊ณต์
void Inc() { counter++; } // ํ ์ค ๊ฐ์ง๋ง ์ค์ 3๋จ๊ณ
counter++ ์ ๊ธฐ๊ณ์ด ์์ค:
1
2
3
load counter, R1 ; R1 โ counter
add R1, 1, R1 ; R1 โ R1 + 1
store R1, counter ; counter โ R1
๋ ์ค๋ ๋๊ฐ ์ธํฐ๋ฆฌ๋น๋๋ฉด:
1
2
3
4
5
6
7
์๊ฐ ์ค๋ ๋ A ์ค๋ ๋ B counter ๋ฉ๋ชจ๋ฆฌ
1 load(0) โ A.R1=0
2 load(0) โ B.R1=0
3 add โ A.R1=1
4 add โ B.R1=1
5 store(1) counter = 1
6 store(1) counter = 1 โ
์์ด๋ฒ๋ฆฐ ๊ฐฑ์
โ Inc()๋ฅผ ๋ ๋ฒ ํ๋๋ฐ counter๊ฐ 2๊ฐ ์๋ 1. ์ด๊ฒ lost update ํํ์ race condition.
์๊ณ ๊ตฌ์ญ (Critical Section)
1
2
3
4
5
6
์๊ณ ๊ตฌ์ญ = ๊ณต์ ์์์ ์ ๊ทผํ๋ ์ฝ๋ ๊ตฌ๊ฐ
ํ์ํ 4๊ฐ์ง ๋ณด์ฅ:
โ ์ํธ ๋ฐฐ์ (Mutual Exclusion) โ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์ง์
โก ์งํ (Progress) โ ์๋ฌด๋ ์ ์ฐ๋ฉด ๋ค์ด๊ฐ ์ ์์ด์ผ
โข ํ๊ณ ๋๊ธฐ (Bounded Wait) โ ๋ฌดํ์ ๊ธฐ๋ค๋ฆฌ์ง ์์์ผ
โฃ ๊ฐ์ ์์ โ CPU ์๋ยท๊ฐ์์ ์์กดํ์ง ๋ง ๊ฒ
Mutex (Mutual Exclusion)
1
2
3
4
5
6
7
8
std::mutex m;
int counter = 0;
void Inc() {
m.lock();
counter++; // ์๊ณ ๊ตฌ์ญ โ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง
m.unlock();
}
๋ฌธ์ : counter++์์ ์์ธ๊ฐ ๋๋ฉด unlock()์ด ์ ํธ์ถ๋ผ deadlock. ์ด๊ฑธ RAII๋ก ์๋ํํ ๊ฒ std::lock_guard (9๋ฒ RAII์ ๋์์ฑ ์์ฉ).
1
2
3
4
void IncSafe() {
std::lock_guard<std::mutex> lock(m); // ์์ฑ ์ lock
counter++; // ์์ธ ๋๋ OK
} // ์๋ฉธ ์ ์๋ unlock
โ Community 18 (Mutex ๋ฝ โ lock_guardยทscopedยทunique)๊ณผ Community 23 (std::mutex ๋ณต์ฌยท์ด๋ ๊ธ์ง)์ด ์ ํํ ์ด ์์ญ.
Deadlock โ 4๊ฐ์ง ์กฐ๊ฑด (Coffman conditions)
๋ค ์กฐ๊ฑด์ด ๋์์ ๋ง์กฑ๋ผ์ผ deadlock ๋ฐ์. ํ๋๋ผ๋ ๊นจ๋ฉด deadlock ํํผ ๊ฐ๋ฅ.
| ์กฐ๊ฑด | ์ค๋ช |
|---|---|
| โ ์ํธ ๋ฐฐ์ (Mutual Exclusion) | ์์์ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์ ์ |
| โก ์ ์ ์ ๋๊ธฐ (Hold and Wait) | ์์์ ๋ ์ฑ ๋ค๋ฅธ ์์์ ๊ธฐ๋ค๋ฆผ |
| โข ๋น์ ์ (No Preemption) | OS๊ฐ ๊ฐ์ ๋ก ์์์ ๋นผ์์ ์ ์์ |
| โฃ ์ํ ๋๊ธฐ (Circular Wait) | ์ค๋ ๋๋ค์ด ์ํ์ผ๋ก ์์์ ๊ธฐ๋ค๋ฆผ |
Deadlock ์๊ฐํ
1
2
3
4
5
6
7
8
9
10
11
12
13
std::mutex A, B;
void T1() {
std::lock_guard<std::mutex> la(A);
std::this_thread::sleep_for(1ms);
std::lock_guard<std::mutex> lb(B); // B๊ฐ T2์ ์กํ์์ผ๋ฉด ์์ํ ๋๊ธฐ
}
void T2() {
std::lock_guard<std::mutex> lb(B);
std::this_thread::sleep_for(1ms);
std::lock_guard<std::mutex> la(A); // A๊ฐ T1์ ์กํ์์ผ๋ฉด ์์ํ ๋๊ธฐ
}
1
2
3
T1: A ์ก์ โ B ๊ธฐ๋ค๋ฆผ
T2: B ์ก์ โ A ๊ธฐ๋ค๋ฆผ
โป ์ํ ๋๊ธฐ โ ๋ ๋ค ๋ฉ์ถค
Deadlock ํํผ ํจํด
1
2
3
4
5
6
7
8
9
10
11
12
13
1. ๋ฝ ์์ ์ ํ๊ธฐ (Lock Ordering)
- ๋ชจ๋ ์ค๋ ๋๊ฐ ํญ์ ๊ฐ์ ์์๋ก ๋ฝ์ ํ๋ (์: ์ฃผ์ ์ค๋ฆ์ฐจ์)
โ ์ํ ๋๊ธฐ ๊นจ์ง
2. std::scoped_lock (C++17) โ ์ฌ๋ฌ mutex ๋์์ ํ๋
std::scoped_lock lk(A, B); // ๋ฐ๋๋ฝ ํํผ ์๊ณ ๋ฆฌ์ฆ ๋ด์ฅ
3. try_lock + ๋ฐฑ์คํ
- ๋ฝ์ ๋ชป ์ก์ผ๋ฉด ๊ฐ์ง๊ณ ์๋ ๋ฝ ํ๊ณ ์ฌ์๋
โ ์ ์ ์ ๋๊ธฐ ๊นจ์ง
4. ๋ฝ ๊ณ์ธต (Lock Hierarchy)
- ๋ฝ์ ๋ ๋ฒจ์ ๋ถ์ฌ, ๋์ ๋ ๋ฒจ์์ ๋ฎ์ ๋ ๋ฒจ ๋ฝ๋ง ํ๋ ๊ฐ๋ฅ
๋ค๋ฅธ ๋์์ฑ ๋ฌธ์ ๋ค
| ๋ฌธ์ | ์ค๋ช | ์์ |
|---|---|---|
| Race condition | ๋์ ์ ๊ทผ์ผ๋ก ๊ฒฐ๊ณผ ๋น๊ฒฐ์ ์ | counter++ |
| Deadlock | ์๋ก์ ๋ฝ์ ๋ฌดํ ๋๊ธฐ | ์ T1/T2 |
| Livelock | ๋ค๋ค ์๋ณด๋ง ํ๋ค๊ฐ ์งํ ์ ๋จ | ๋ ์ฌ๋์ด ๋ณต๋์์ ๊ณ์ ๊ฐ์ ๋ฐฉํฅ์ผ๋ก ๋นํด |
| Starvation | ํน์ ์ค๋ ๋๊ฐ ์์ํ ์์ ๋ชป ๋ฐ์ | ์ฐ์ ์์ ๋ฎ์์ ๋งค๋ฒ ๋ฐ๋ฆผ |
| Priority Inversion | ๋ฎ์ ์ฐ์ ์์๊ฐ ๋ฝ์ ๋ค๊ณ , ๋์ ์ฐ์ ์์๊ฐ ๊ธฐ๋ค๋ฆผ | NASA Mars Pathfinder ์ฌ๋ก |
Atomic โ Lock-Free ๋์
1
2
3
4
5
6
std::atomic<int> counter{0};
void Inc() {
counter.fetch_add(1); // CPU ๋ช
๋ น์ด๋ก ์์์ ๋ณด์ฅ (LOCK XADD ๋ฑ)
// ๋๋ counter++; (์ค๋ฒ๋ก๋ฉ๋จ)
}
โ ๋จ์ํ read-modify-write๋ mutex๋ณด๋ค atomic์ด ํจ์ฌ ๋น ๋ฆ. 11๋ฒ์์ ๋ณธ shared_ptr ์ ์ด ๋ธ๋ก์ reference counter๋ atomic์ผ๋ก ๊ตฌํ๋จ.
7. ๋ฉํฐํ๋ก์ธ์ค vs ๋ฉํฐ์ค๋ ๋ โ ์ธ์ ๋ฌด์์ ์ฐ๋
ํต์ฌ ํ ๋ฌธ์ฅ
๊ฒฉ๋ฆฌยท์์ ์ฑยท๋ณด์์ด ์ฐ์ ์ด๋ฉด ๋ฉํฐํ๋ก์ธ์ค, ์๋ยทํต์ ๋น๋ยท์์ ํจ์จ์ด ์ฐ์ ์ด๋ฉด ๋ฉํฐ์ค๋ ๋.
๋น๊ต ํ
| ๊ด์ | ๋ฉํฐํ๋ก์ธ์ค | ๋ฉํฐ์ค๋ ๋ |
|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ๊ฒฉ๋ฆฌ | ๊ฐํจ (๋ค๋ฅธ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ) | ์์ (๊ฐ์ ๊ณต๊ฐ) |
| ํ์ชฝ ํฌ๋์ ์ํฅ | ๋ค๋ฅธ ํ๋ก์ธ์ค ์ํฅ X | ์ ์ฒด ํ๋ก์ธ์ค ๋ค์ด |
| ์์ฑ ๋น์ฉ | ํผ (fork/CreateProcess) | ์์ (pthread_create/std::thread) |
| ์ปจํ ์คํธ ์ค์์นญ | ๋น์ (TLBยทํ์ด์ง ํ ์ด๋ธ) | ์ผ ํธ |
| ํต์ ๋น์ฉ | IPC โ ๋น์ | ๊ณต์ ๋ฉ๋ชจ๋ฆฌ โ 0 |
| ๋๊ธฐํ ๋ถ๋ด | ๋ฎ์ (์์ฐ์ค๋ฌ์ด ๊ฒฉ๋ฆฌ) | ๋์ (mutex ๋ฑ ํ์) |
| ๋๋ฒ๊น ๋์ด๋ | ๋น๊ต์ ์ฌ์ (๊ฒฉ๋ฆฌ) | ์ด๋ ค์ (race condition ์ฌํ ์ด๋ ค์) |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ | ํผ (๊ฐ ํ๋ก์ธ์ค๊ฐ ์๊ธฐ ์์ญ) | ์์ (๋๋ถ๋ถ ๊ณต์ ) |
| ๋ณด์ ๊ฒฉ๋ฆฌ | ๊ฐํจ | ์์ |
์ฌ๋ก ๋ถ์
Chrome โ ํญ๋ง๋ค ํ๋ก์ธ์ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Chrome ์ํคํ
์ฒ:
โโ ๋ธ๋ผ์ฐ์ ํ๋ก์ธ์ค (UIยท๋คํธ์ํฌยท๋์คํฌ I/O)
โโ ๋ ๋๋ฌ ํ๋ก์ธ์ค 1 (ํญ 1) โ ํญ 1์ด ํฌ๋์ํด๋ ๋ค๋ฅธ ํญ ์ ์ฃฝ์
โโ ๋ ๋๋ฌ ํ๋ก์ธ์ค 2 (ํญ 2)
โโ GPU ํ๋ก์ธ์ค
โโ ํ๋ฌ๊ทธ์ธ ํ๋ก์ธ์ค
์ด์ :
โ ๋ณด์ โ ์
์ฑ ์ฌ์ดํธ๊ฐ ๋ค๋ฅธ ํญ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผ ๋ชป ํจ (sandbox)
โก ์์ ์ฑ โ ํ ํญ ํฌ๋์ = ๊ทธ ํญ๋ง ์ข
๋ฃ
โข ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฒฉ๋ฆฌ โ ํญ ๋ซ์ผ๋ฉด ๊ทธ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ ์ ๋ถ ํ์
๋๊ฐ:
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ (ํญ๋ง๋ค ์์ญ MB ๋ฒ ์ด์ค)
- IPC ๋น์ฉ (๋ธ๋ผ์ฐ์ โ ๋ ๋๋ฌ ํต์ )
PostgreSQL โ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค (์ ํต์ )
1
2
3
4
5
6
7
์ ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ โ fork() โ ์์ ํ๋ก์ธ์ค๊ฐ ๊ทธ ์ฐ๊ฒฐ ์ฒ๋ฆฌ
์ด์ :
โ ํ ์ฟผ๋ฆฌ๊ฐ ์ฃฝ์ด๋ ๋ค๋ฅธ ์ฐ๊ฒฐ ์ํฅ X
โก ๋ฉ๋ชจ๋ฆฌ ๊ฒฉ๋ฆฌ (๋ณด์)
๋๊ฐ:
- fork ๋น์ฉ (Postgres๊ฐ connection pooling์ ๊ถ์ฅํ๋ ์ด์ )
- ๊ณต์ ๋ฐ์ดํฐ๋ shared memory๋ก ๋ฐ๋ก ๊ด๋ฆฌ
Apache vs Nginx
1
2
3
4
5
Apache (์ ํต prefork): ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค โ ์์ ์ ์ด๋ ๋ฌด๊ฑฐ์
Apache (worker MPM): ํ๋ก์ธ์ค + ์ค๋ ๋ ํผํฉ
Nginx: ์ด๋ฒคํธ ๋ฃจํ + ์์ปค ํ๋ก์ธ์ค (์ ์ ์) โ ํจ์จ์
์ ํ ๊ธฐ์ค์ ๋์ ์ ์ ๊ท๋ชจ์ ๊ฒฉ๋ฆฌ ์๊ตฌ.
๊ฒ์ ์์ง โ ๋ฉํฐ์ค๋ ๋
1
2
3
4
5
6
7
8
9
์ด์ :
โ ๋งค ํ๋ ์ 16.6ms (60fps) โ IPC ๋น์ฉ์ ๊ฒฌ๋ ์ ์์
โก ๊ฒ์ ๊ฐ์ฒด ์๋ง ๊ฐ๋ฅผ ๋งค ํ๋ ์ ์
๋ฐ์ดํธ โ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ํ์
โข ๊ฒ์ ์ค๋ ๋(๋ก์ง) โ ๋ ๋ ์ค๋ ๋(GPU ๋ช
๋ น) ๋๊ธฐํ ์์ฃผ
๋๊ฐ:
- race condition ์ํ (mutexยทatomicยทlock-free ์๋ฃ๊ตฌ์กฐ ๋ค์)
- ํ ์ค๋ ๋ ํฌ๋์ = ๊ฒ์ ๋ค์ด
- ๋๋ฒ๊น
๋์ด๋ (๋ฉํฐ์ค๋ ๋ ๋๋ฒ๊ฑฐ ํ์)
์น ์๋ฒ ์์ปค (Node.js / ์์ปค ํ)
1
2
3
Node.js: ๋จ์ผ ์ค๋ ๋ + ์ด๋ฒคํธ ๋ฃจํ (CPU ์์
์ worker_threads๋ก ์์)
Java/Tomcat: ์ค๋ ๋ ํ (์์ฒญ๋น ์ค๋ ๋)
Go: ๊ณ ๋ฃจํด (M:N) โ ์ค๋ ๋๋ณด๋ค ๋ ๊ฐ๋ฒผ์ด ์ถ์ํ
๊ฒฐ์ ํ๋ฆ
1
2
3
4
5
6
7
8
9
10
11
12
13
์์ฒญ ์ฒ๋ฆฌ/์์
์ข
๋ฅ๋?
โ
โโโ ๊ฒฉ๋ฆฌยท๋ณด์ ์ฐ์ (๋ธ๋ผ์ฐ์ ํญ, DB ์ฐ๊ฒฐ)
โ โโโ ๋ฉํฐํ๋ก์ธ์ค
โ
โโโ ์งง์ ๋น๋์ ๋ฌด๊ฑฐ์ด ํต์ (๋ถ์ฐ ์์คํ
)
โ โโโ ๋ฉํฐํ๋ก์ธ์ค + IPC (๋๋ ๋คํธ์ํฌ)
โ
โโโ ์ฆ์ ํต์ ยท๋ฎ์ ์ง์ฐ (๊ฒ์, ์น ์๋ฒ ์์ปค)
โ โโโ ๋ฉํฐ์ค๋ ๋ + ๋๊ธฐํ
โ
โโโ ๋งค์ฐ ๋ง์ ๋์ ์์
(์์ญ๋ง connection)
โโโ async/await ๋๋ ์ฝ๋ฃจํด (์ด๋ฒคํธ ๋ฃจํ ๋ชจ๋ธ)
8. ์ฌ์ฉ์ ์ค๋ ๋ vs ์ปค๋ ์ค๋ ๋ โ 1:1 / N:1 / M:N ๋ชจ๋ธ
ํต์ฌ ํ ๋ฌธ์ฅ
์ฌ์ฉ์ ์ค๋ ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๊ด๋ฆฌ(๋น ๋ฆยท์์คํ ์ฝ์ ์ฝํจ), ์ปค๋ ์ค๋ ๋๋ OS๊ฐ ๊ด๋ฆฌ(์์คํ ์ฝ ์์ ยท์์ฑ ๋น์ฉ ํผ), ๊ทธ๋ฆฌ๊ณ ๋์ ์ด๋ป๊ฒ ๋งคํํ๋๋๊ฐ 1:1 / N:1 / M:N ๋ชจ๋ธ์ ๋๋ค.
์ฌ์ฉ์ vs ์ปค๋ ์ค๋ ๋
| ํญ๋ชฉ | ์ฌ์ฉ์ ์ค๋ ๋ | ์ปค๋ ์ค๋ ๋ |
|---|---|---|
| ๊ด๋ฆฌ ์ฃผ์ฒด | ์ฌ์ฉ์ ๊ณต๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์์ Java green thread) | OS ์ปค๋ |
| ์์ฑ ๋น์ฉ | ๋งค์ฐ ์์ | ํผ (์์คํ ์ฝยท์ปค๋ ์๋ฃ๊ตฌ์กฐ) |
| ์ปจํ ์คํธ ์ค์์นญ | ๋น ๋ฆ (์ปค๋ ์ง์ X) | ๋น์ (์ปค๋ ๋ชจ๋ ์ ํ) |
| ์์คํ ์ฝ ์ฐจ๋จ ์ | ์ ์ฒด ํ๋ก์ธ์ค ์ฐจ๋จ (์ปค๋์ ์ฌ์ฉ์ ์ค๋ ๋ ๋ชจ๋ฆ) | ๊ทธ ์ค๋ ๋๋ง ์ฐจ๋จ, ๋ค๋ฅธ ์ค๋ ๋ ์งํ |
| ๋ฉํฐ ์ฝ์ด ํ์ฉ | ์ด๋ ค์ | ์์ฐ์ค๋ฌ์ |
1:1 ๋ชจ๋ธ (Linux pthread, Windows Thread, std::thread)
1
2
3
4
5
6
7
8
9
10
์ฌ์ฉ์ ์ค๋ ๋ 1๊ฐ โ ์ปค๋ ์ค๋ ๋ 1๊ฐ
์ฅ์ :
โ ์์คํ
์ฝ ์ฐจ๋จํด๋ ๊ทธ ์ค๋ ๋๋ง ์ํฅ
โก ๋ฉํฐ ์ฝ์ด ํ์ฉ ์์ฐ์ค๋ฌ์
โข ๋จ์ํ ๋งคํ
๋จ์ :
โ ์์ฑ ๋น์ฉ ํผ
โก ๋์ ์ค๋ ๋ ์์ OS ์ ํ
โ ํ๋ OS์ ํ์ค (WindowsยทLinuxยทmacOS). C++ std::thread๋ 1:1.
N:1 ๋ชจ๋ธ (์์ Java green thread, GNU Pth)
1
2
3
4
5
6
7
8
9
์ฌ๋ฌ ์ฌ์ฉ์ ์ค๋ ๋ โ ์ปค๋ ์ค๋ ๋ 1๊ฐ
์ฅ์ :
โ ๋งค์ฐ ๊ฐ๋ฒผ์ (์ปค๋ ์๋ฃ๊ตฌ์กฐ 1๊ฐ)
โก ์ปจํ
์คํธ ์ค์์นญ ๋งค์ฐ ๋น ๋ฆ
๋จ์ :
โ ํ ์ค๋ ๋๊ฐ ์์คํ
์ฝ ์ฐจ๋จ โ ์ ๋ถ ์ฐจ๋จ
โก ๋ฉํฐ ์ฝ์ด ํ์ฉ ๋ถ๊ฐ
โ ํ๋์ ๊ฑฐ์ ์ ์.
M:N ๋ชจ๋ธ (Go goroutine, Java Loom virtual thread)
1
2
3
4
5
6
7
8
9
10
M๊ฐ ์ฌ์ฉ์ ์ค๋ ๋ โ N๊ฐ ์ปค๋ ์ค๋ ๋ (M >> N)
์ฅ์ :
โ ๊ฐ๋ฒผ์ (์ฌ์ฉ์ ๊ณต๊ฐ ์ค์ผ์ค๋ง)
โก ๋ฉํฐ ์ฝ์ด ํ์ฉ (์ปค๋ ์ค๋ ๋๊ฐ N๊ฐ)
โข ์์คํ
์ฝ ์ฐจ๋จ ์ ๋ค๋ฅธ ์ฌ์ฉ์ ์ค๋ ๋๋ฅผ ๋ค๋ฅธ ์ปค๋ ์ค๋ ๋์ ์ฌ๋ฐฐ์น
๋จ์ :
โ ๋ฐํ์์ด ๋ณต์ก (์ค์ผ์ค๋ฌยท๋ธ๋กํน ์ฒ๋ฆฌ)
โก ๋๋ฒ๊น
์ด๋ ค์
โ Go๋ ์๋ง ๊ฐ ๊ณ ๋ฃจํด์ 4~16๊ฐ OS ์ค๋ ๋ ์์์ ๋๋ฆฝ๋๋ค. Java๋ 21์์ virtual thread ๋์ .
์์ฝ
1
2
3
1:1 โ std::thread, pthread, Windows Thread (๊ฐ์ฅ ์ผ๋ฐ)
N:1 โ ์์ Java green thread (์ญ์ฌ์ )
M:N โ Go goroutine, Java Loom virtual thread (์ต์ ํธ๋ ๋)
9. C++ ์ฝ๋ ์์ โ std::thread / mutex / async / atomic
9.1 std::thread โ ๊ฐ์ฅ ๊ธฐ๋ณธ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <thread>
void Worker(int id) {
std::cout << "Thread " << id << " running\n";
}
int main() {
std::thread t1(Worker, 1);
std::thread t2(Worker, 2);
// ๋๋ค๋ ๊ฐ๋ฅ
std::thread t3([]{ std::cout << "lambda thread\n"; });
t1.join(); // t1์ด ๋๋ ๋๊น์ง ๋ฉ์ธ์ด ๋๊ธฐ
t2.join();
t3.join();
}
๋ฐ๋์
join()๋๋detach()๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ์ ํ๋ฉดstd::thread์๋ฉธ์๊ฐstd::terminate()ํธ์ถ โ ํ๋ก์ธ์ค ๊ฐ์ ์ข ๋ฃ.
9.2 std::mutex + std::lock_guard โ RAII ๋ฝ (9๋ฒ ํ๊ท)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <mutex>
#include <thread>
#include <vector>
std::mutex m;
int counter = 0;
void Inc(int times) {
for (int i = 0; i < times; ++i) {
std::lock_guard<std::mutex> lock(m); // ์์ฑ ์ lock
++counter; // ์๊ณ ๊ตฌ์ญ
} // ์๋ฉธ ์ ์๋ unlock
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i)
threads.emplace_back(Inc, 1000);
for (auto& t : threads) t.join();
std::cout << counter; // ์ ํํ 10000
}
โ lock_guard ์์ด m.lock()/m.unlock() ์ง์ ํธ์ถํ๋ฉด ์์ธ ๋ฐ์ ์ unlock ๋๋ฝ โ deadlock. 9๋ฒ RAII๊ฐ ๋์์ฑ์์๋ ๊ทธ๋๋ก ์ ์ฉ๋จ.
9.3 std::scoped_lock (C++17) โ ์ฌ๋ฌ mutex ๋์์
1
2
3
4
5
6
std::mutex a, b;
void Transfer(/* ... */) {
std::scoped_lock lk(a, b); // ๋ ๋ค ์์ ํ๊ฒ lock (deadlock ํํผ)
// ...
}
โ ๋ mutex๋ฅผ ํญ์ ๊ฐ์ ์์๋ก ์ก์ง ์์๋ ๋ฐ๋๋ฝ์ด ์ ๋๋๋ก ๋ด๋ถ์ ์ผ๋ก try_lock + back-off๋ฅผ ํจ.
9.4 std::async / std::future โ ๋น๋๊ธฐ ์์
1
2
3
4
5
6
7
8
9
10
11
12
#include <future>
int Compute() {
std::this_thread::sleep_for(std::chrono::seconds(1));
return 42;
}
int main() {
std::future<int> f = std::async(std::launch::async, Compute);
// ... ๋ค๋ฅธ ์ผ ํ๋ค๊ฐ
int result = f.get(); // ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ๋ฐ๊ธฐ
}
โ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ๋ช ์์ ์ฑ๋์ด ์์ด์ race condition ์์ด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฐ๋ฅ.
9.5 std::atomic โ Lock-Free
1
2
3
4
5
6
7
8
9
#include <atomic>
std::atomic<int> counter{0};
void Inc(int times) {
for (int i = 0; i < times; ++i)
counter.fetch_add(1); // ์์์
// ๋๋ counter++; (์ค๋ฒ๋ก๋ฉ๋จ)
}
โ ๋จ์ ์นด์ดํฐ ์ฆ๊ฐ์ mutex๋ณด๋ค atomic์ด 5~10๋ฐฐ ๋น ๋ฆ. ๋จ, ๋ณต์กํ ์๊ณ ๊ตฌ์ญ(์ฌ๋ฌ ๋ณ์ ๋์ ๋ณ๊ฒฝ)์ mutex ํ์.
9.6 condition_variable โ ์ค๋ ๋ ๊ฐ ์ ํธ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
bool ready = false;
void Producer() {
{
std::lock_guard<std::mutex> lock(m);
ready = true;
}
cv.notify_one(); // ๋๊ธฐ ์ค์ธ ์ค๋ ๋ ๊นจ์
}
void Consumer() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, []{ return ready; }); // ready==true๊ฐ ๋ ๋๊น์ง ๋๊ธฐ
// ์๊ณ ๊ตฌ์ญ ์ง์
(lock ํ๋ ์ํ)
}
โ Producer-Consumer ํจํด, ์์ ํ ๋ฑ์ ํ์.
9.7 std::jthread (C++20) โ ์๋ join + ํ์กฐ์ ์ทจ์
1
2
3
4
5
6
7
8
9
10
11
12
#include <thread>
void Worker(std::stop_token st, int id) {
while (!st.stop_requested()) {
// ...
}
}
int main() {
std::jthread jt(Worker, 1);
// ๋ฉ์ธ ์ข
๋ฃ ์ ์๋์ผ๋ก stop_requested + join
}
โ std::thread์ join ๋๋ฝ ์ฌ๊ณ ๋ฅผ ๋ง๋ C++20 ๊ฐ์ ํ.
10. ์ธ๋ฆฌ์ผ์์์ ์ค๋ ๋ โ ๊ฒ์ ์ค๋ ๋ / ๋ ๋ ์ค๋ ๋ / FRunnable
ํต์ฌ ํ ๋ฌธ์ฅ
์ธ๋ฆฌ์ผ ์์ง์ ๊ฒ์ ๋ก์ง๊ณผ ๋ ๋๋ง์ ๋ค๋ฅธ ์ค๋ ๋๋ก ๋ถ๋ฆฌํด GPU์ CPU๋ฅผ ๋ณ๋ ฌ๋ก ํ์ฉํ๊ณ ,
FRunnable/AsyncTask/ParallelFor๋ก ์์ปค ์ค๋ ๋๋ฅผ ์ถ์ํํ๋ฉฐ, RAII ๋ฝFScopeLock์ผ๋ก ๋๊ธฐํํฉ๋๋ค.
10.1 ์ธ๋ฆฌ์ผ์ ์ฃผ์ ์ค๋ ๋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
๊ฒ์ ์ค๋ ๋ (Game Thread / Main Thread)
- AActor, AGameMode, UWorld ๋ฑ ๋ชจ๋ ๊ฒ์ํ๋ ์ด ๋ก์ง
- Tick(), ์
๋ ฅ ์ฒ๋ฆฌ, UI ๊ฐฑ์ (UMG)
- "๊ฒ์ ์ค๋ ๋์์๋ง UObjectยทAActor ์ ๊ทผ ๊ฐ๋ฅ" ์ด ๊ธฐ๋ณธ ๋ฃฐ
๋ ๋ ์ค๋ ๋ (Render Thread)
- ๊ฒ์ ์ค๋ ๋๊ฐ ๋ง๋ ๋ช
๋ น(์: Draw Indexed Primitive)์ GPU ๋ช
๋ น์ผ๋ก ๋ณํ
- RHI(Rendering Hardware Interface) ํธ์ถ
- ๊ฒ์ ์ค๋ ๋์ 1ํ๋ ์ ์ ๋ ๋ฆ๊ฒ ์งํ (์ง์ฐ ๋ ๋๋ง)
RHI ์ค๋ ๋ / GPU ์ค๋ ๋
- ์ค์ GPU ๋ช
๋ น์ด ๋์คํจ์น
- ๋ ๋ ์ค๋ ๋์ ๋ช
๋ น์ ๋ฐ์ ์ฒ๋ฆฌ
์์ปค ํ (Task Graph / Async Tasks)
- ParallelFor, AsyncTask๋ก ๋์คํจ์น๋ ์์
์ฒ๋ฆฌ
- ์ฝ์ด ์๋งํผ ์๋ ์์ฑ
10.2 ๊ฒ์ ์ค๋ ๋ / ๋ ๋ ์ค๋ ๋ ๋ถ๋ฆฌ โ ์ ํ์ํ๊ฐ
1
2
3
4
5
6
7
8
9
10
[์ฑ๊ธ ์ค๋ ๋ ๋ชจ๋ธ] 60fps ๋ชฉํ โ 16.6ms / ํ๋ ์
Tick โ Draw โ Tick โ Draw ...
CPU์ GPU๊ฐ ์ง๋ ฌํ๋์ด ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋ถ๊ฐ
[๋ฉํฐ ์ค๋ ๋ ๋ชจ๋ธ]
๊ฒ์ ์ค๋ ๋: Tick(1) โ Tick(2) โ Tick(3) ...
๋ ๋ ์ค๋ ๋: Draw(1) โ Draw(2) ... (1ํ๋ ์ ์ง์ฐ)
GPU: GPU(1) โ GPU(2) ...
โ ๊ฐ์ 16.6ms ์์ ๋ ๋ง์ ์์
โ ๊ฒ์ ์์ง์ด IPC ๋ถ๋ด์ ์ ๋ ๋ชป ๊ฒฌ๋๋ ํ๊ฒฝ์ ์ ํ. ๊ฐ์ ํ๋ก์ธ์ค์ ๋ ์ค๋ ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํด์ผ๋ง 60fps๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
10.3 FRunnable / FRunnableThread โ ์์ปค ์ค๋ ๋ ๋ง๋ค๊ธฐ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class FMyWorker : public FRunnable
{
public:
virtual bool Init() override { return true; }
virtual uint32 Run() override
{
while (!bStopped)
{
// ๋ฌด๊ฑฐ์ด ์์
(๋คํธ์ํฌ, ํ์ผ IO, ์ฐ์ฐ)
}
return 0;
}
virtual void Stop() override { bStopped = true; }
private:
std::atomic<bool> bStopped{false};
};
// ์์
FMyWorker* Worker = new FMyWorker();
FRunnableThread* Thread = FRunnableThread::Create(Worker, TEXT("MyWorker"));
โ std::thread์ ์ธ๋ฆฌ์ผ ๋ฒ์ . ๋ฉํฐ ํ๋ซํผ ์ถ์ํ(WindowsยทLinuxยท์ฝ์) ์ ๊ณต.
10.4 AsyncTask โ ์งง์ ์์ ํ์ ๋์คํจ์น
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "Async/AsyncWork.h"
AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, []()
{
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ปค์์ ์คํ
HeavyWork();
// ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ ์ค๋ ๋๋ก ๋ค์
AsyncTask(ENamedThreads::GameThread, []()
{
UpdateUI();
});
});
โ โ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฌด๊ฑฐ์ด ์ผ โ ๋๋๋ฉด ๊ฒ์ ์ค๋ ๋์์ UI ๊ฐฑ์ โ ํจํด. UE์ ํ์ค.
10.5 ParallelFor โ ๋ฐ์ดํฐ ๋ณ๋ ฌ
1
2
3
4
5
6
7
#include "Async/ParallelFor.h"
ParallelFor(NumActors, [&](int32 Index)
{
// Index 0..NumActors-1์ ์์ปค ํ์ด ๋ถ๋ด
Actors[Index]->ProcessHeavy();
});
โ for ๋ฃจํ๋ฅผ ์๋ ๋ณ๋ ฌํ. ๊ฒ์ ์ค๋ ๋์์ ํธ์ถํด๋ ์์ปค ์ค๋ ๋๊ฐ ๋ถ๋ด.
10.6 FCriticalSection / FScopeLock โ RAII ๋ฝ (Community 7 ํ๊ท)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "HAL/CriticalSection.h"
class FMyData
{
public:
void Add(int32 Value)
{
FScopeLock Lock(&CS); // ์์ฑ ์ lock, ์๋ฉธ ์ unlock
Data.Add(Value);
}
private:
mutable FCriticalSection CS;
TArray<int32> Data;
};
โ std::lock_guard์ ์ธ๋ฆฌ์ผ ๋์. 9๋ฒ RAII์ 18๋ฒ Community 18(Mutex ๋ฝ)์ ํจํด ๊ทธ๋๋ก.
10.7 ๊ฒ์ ์ค๋ ๋ ์ฒดํฌ ๋งคํฌ๋ก
1
2
check(IsInGameThread()); // ๊ฒ์ ์ค๋ ๋์์ ํธ์ถ๋๋์ง ๊ฒ์ฆ
check(IsInRenderingThread()); // ๋ ๋ ์ค๋ ๋์์ ํธ์ถ๋๋์ง ๊ฒ์ฆ
โ UObjectยทAActor ์กฐ์ ์ฝ๋๋ ๋ณดํต check(IsInGameThread())๋ก ์์. ๋ฉํฐ์ค๋ ๋ ์์ ์๋ฐ ๋๋ฒ๊น
ํต์ฌ.
10.8 ์ธ๋ฆฌ์ผ โ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋์
| std:: | Unreal |
|---|---|
std::thread | FRunnable + FRunnableThread |
std::mutex | FCriticalSection |
std::lock_guard | FScopeLock |
std::atomic<T> | TAtomic<T> ๋๋ ๊ทธ๋๋ก std::atomic |
std::async / std::future | AsyncTask / TFuture / TPromise |
std::condition_variable | FEvent (Trigger / Wait) |
std::this_thread::sleep_for | FPlatformProcess::Sleep |
โ ์ธ๋ฆฌ์ผ์ ์์ฒด ์ถ์ํ ์์ฃผ์ง๋ง ๋ด๋ถ์ ์ผ๋ก๋ ๊ฐ์ OS ํ๋ฆฌ๋ฏธํฐ๋ธ.
11. ๊ผฌ๋ฆฌ์ง๋ฌธ ์์ ๊ฒฝ๋ก
Q1. โํ๋ก์ธ์ค์ ์ค๋ ๋์ ์ฐจ์ด๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก ์์ฝํ๋ฉด?โ
ํ๋ก์ธ์ค๋ ์์์ ์์ ํ๋ ๋จ์, ์ค๋ ๋๋ ๊ทธ ์์ ์์์ ์คํ๋๋ ํ๋ฆ์ ๋๋ค. ํ๋ก์ธ์ค๋ ๋ฉ๋ชจ๋ฆฌยทํธ๋คยท๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ์ง๊ณ , ์ค๋ ๋๋ ๊ฐ์ ํ๋ก์ธ์ค์ ์ฝ๋ยท๋ฐ์ดํฐยทํ์ ๊ณต์ ํ๋ฉด์ ์๊ธฐ ์คํ๊ณผ ๋ ์ง์คํฐยทPC๋ง ๋ฐ๋ก ๊ฐ์ต๋๋ค. ๊ทธ๋์ ์ค๋ ๋ ๊ฐ ํต์ ์ ๋น ๋ฅด์ง๋ง ๋๊ธฐํ ๋ฌธ์ ๊ฐ ๋ฐ๋ผ์ค๊ณ , ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ๊ฒฉ๋ฆฌ๊ฐ ์ข์ง๋ง IPC ๋น์ฉ์ด ๋ญ๋๋ค.
Q2. โ์ค๋ ๋๋ผ๋ฆฌ ๋ฌด์์ ๊ณต์ ํ๊ณ ๋ฌด์์ ๊ณต์ ํ์ง ์๋์?โ
๊ณต์ : ์ฝ๋ ์์ญ, ์ ์ญยทstatic ๋ฐ์ดํฐ, ํ, ํ์ผ ๋์คํฌ๋ฆฝํฐ, ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ์ ์ฒด. ๋ ๋ฆฝ: ์คํ, ๋ ์ง์คํฐ ์ปจํ ์คํธ(PCยทSPยท๋ฒ์ฉ ๋ ์ง์คํฐ), TID, ์๊ทธ๋ ๋ง์คํฌ, TLS(Thread Local Storage). ์ฌ๊ธฐ์ ๊ฒฐ์ ์ ์ธ ๊ฑด ํ์ด ๊ณต์ ๋๋ค๋ ์ ์ ๋๋ค โ
new๋ก ํ ๋นํ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ํจ๊ป ๋ณด๊ธฐ ๋๋ฌธ์ mutex ๊ฐ์ ๋๊ธฐํ๊ฐ ํ์ํด์ง๋๋ค.
Q3. โ์ค๋ ๋์ ์ปจํ ์คํธ ์ค์์นญ์ด ํ๋ก์ธ์ค๋ณด๋ค ์ ๋น ๋ฅธ๊ฐ์?โ
๊ฐ์ฅ ํฐ ์ด์ ๋ TLB์ ํ์ด์ง ํ ์ด๋ธ์ ๊ทธ๋๋ก ๋๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ๋ก์ธ์ค ์ ํ์ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ด ๋ฐ๋๋ ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค ๋ ์ง์คํฐ(x86 CR3)๋ฅผ ๊ต์ฒดํ๊ณ TLB๋ฅผ ๋น์์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์งํ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ๋ชจ๋ TLB miss๊ฐ ๋์ ํ์ด์ง ํ ์ด๋ธ ์ํฌ๋ฅผ ๋ค์ ํด์ผ ํฉ๋๋ค. L1ยทL2 ์บ์๋ ์ฐจ๊ฐ์์ง์ฃ . ์ค๋ ๋ ์ ํ์ ๊ฐ์ ํ๋ก์ธ์ค ์์์ ์ผ์ด๋๋ ์ด ๋ชจ๋ ๊ณผ์ ์ด ์๋ต๋๊ณ ๋ ์ง์คํฐ๋ง ๊ต์ฒดํฉ๋๋ค. ๊ทธ๋์ ์ผ๋ฐ์ ์ผ๋ก 5~10๋ฐฐ ๋น ๋ฆ ๋๋ค.
Q4. โ๋ ์ค๋ ๋๊ฐ ๊ฐ์ ๋ณ์์ ๋์์ ์ ๊ทผํ๋ฉด ๋ฌด์จ ์ผ์ด ์๊ธฐ๋์?โ
race condition์ด ๋ฐ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด
counter++๋ ์ฌ์ค์ loadยทaddยทstore ์ธ ๋จ๊ณ๋ผ, ๋ ์ค๋ ๋๊ฐ ์ธํฐ๋ฆฌ๋น๋๋ฉด ํ ์ชฝ ๊ฐฑ์ ์ด ์ฌ๋ผ์ง๋ lost update๊ฐ ์ผ์ด๋ฉ๋๋ค. ๊ฒฐ๊ณผ๊ฐ ๋น๊ฒฐ์ ์ ์ด๊ณ ๋๋ฒ๊น ๋ ์ด๋ ต์ต๋๋ค. ํด๊ฒฐ์ฑ ์ ์๊ณ ๊ตฌ์ญ(critical section)์ mutex๋ก ๋ณดํธํ๊ฑฐ๋, ๋จ์ํ ์นด์ดํฐ๋ผ๋ฉดstd::atomic์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋๋ค. C++์์std::lock_guard๋std::scoped_lock๊ฐ์ RAII ๋ฝ์ ์จ์ ์์ธ ์์ ์ฑ๋ ๊ฐ์ด ๋ณด์ฅํฉ๋๋ค.
Q5. โdeadlock์ด ๋ญ๊ฐ์? 4๊ฐ์ง ์กฐ๊ฑด ์๊ณ ๊ณ์ ๊ฐ์?โ
deadlock์ ๋ ๊ฐ ์ด์์ ์ค๋ ๋๊ฐ ์๋ก์ ์์์ ๋ฌดํํ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ์์ํ ๋ฉ์ถ๋ ์ํ์ ๋๋ค. Coffman conditions๋ผ ๋ถ๋ฅด๋ 4๊ฐ์ง ์กฐ๊ฑด์ด ๋์์ ๋ง์กฑ๋ผ์ผ ๋ฐ์ํฉ๋๋ค โ โ ์ํธ ๋ฐฐ์ (์์์ ํ ๋ฒ์ ํ๋๋ง), โก ์ ์ ์ ๋๊ธฐ(์์์ ๋ ์ฑ ๋ค๋ฅธ ์์ ๋๊ธฐ), โข ๋น์ ์ (๊ฐ์ ๋ก ๋นผ์์ ์ ์์), โฃ ์ํ ๋๊ธฐ(์ํ์ผ๋ก ๊ธฐ๋ค๋ฆผ). ํํผ ๋ฐฉ๋ฒ์ ๋ฝ ์์๋ฅผ ์ ํด์ ์ํ ๋๊ธฐ๋ฅผ ๊นจ๊ฑฐ๋, C++17์
std::scoped_lock์ผ๋ก ์ฌ๋ฌ mutex๋ฅผ ๋์์ ์์ ํ๊ฒ ์ก๊ฑฐ๋, try_lock + back-off๋ก ์ ์ ์ ๋๊ธฐ๋ฅผ ๊นจ๋ ๋ฐฉ์์ ๋๋ค.
Q6. โChrome์ ์ ํญ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ์ฐ๋์?โ
์ธ ๊ฐ์ง ์ด์ ์ ๋๋ค. ์ฒซ์งธ ๋ณด์ โ ์ ์ฑ ์ฌ์ดํธ๊ฐ ๋ค๋ฅธ ํญ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก OS ๋ ๋ฒจ ๊ฒฉ๋ฆฌ(sandbox)๋ฅผ ํ์ฉํฉ๋๋ค. ๋์งธ ์์ ์ฑ โ ํ ํญ์ด ํฌ๋์ํด๋ ๊ทธ ํ๋ก์ธ์ค๋ง ์ฃฝ์ด์ ๋๋จธ์ง ํญ์ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค. ์ ์งธ ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฒฉ๋ฆฌ โ ํญ์ ๋ซ์ผ๋ฉด ๊ทธ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ OS๊ฐ ํต์งธ๋ก ํ์ํ๋ฏ๋ก ๋์๊ฐ ๋์ ๋์ง ์์ต๋๋ค. ๋๊ฐ๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ IPC ๋น์ฉ์ธ๋ฐ, ๋ณด์๊ณผ ์์ ์ฑ์ด ๊ทธ๋งํผ ์ค์ํด์ ๋ฐ์๋ค์ด๋ ํธ๋ ์ด๋์คํ์ ๋๋ค.
Q7. โ๊ทธ๋ผ ๊ฒ์ ์์ง์ ์ ๋ฉํฐ์ค๋ ๋๋ฅผ ์ฐ๋์?โ
๋งค ํ๋ ์ 16.6ms ์์ ๋ชจ๋ ์ผ์ ๋๋ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค(60fps ๊ธฐ์ค). ํ๋ก์ธ์ค ๊ฐ IPC ๋น์ฉ์ ๋ง์ดํฌ๋ก์ด ๋จ์๋ก ๋์ ๋๊ณ ๊ฒ์ ๊ฐ์ฒด ์๋ง ๊ฐ๋ฅผ ๋งค ํ๋ ์ ๋๊ธฐํํ๋ ค๋ฉด ๊ฒฌ๋ ์๊ฐ ์์ต๋๋ค. ๊ทธ๋์ ๊ฐ์ ํ๋ก์ธ์ค ์์์ ๊ฒ์ ์ค๋ ๋(๋ก์ง)์ ๋ ๋ ์ค๋ ๋(GPU ๋ช ๋ น)๋ฅผ ๋ถ๋ฆฌํด ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ก ํต์ ํฉ๋๋ค. ๋์ race condition ์ํ์ ์๊ณ mutexยทatomicยทlock-free ์๋ฃ๊ตฌ์กฐ๋ก ๋ณดํธํฉ๋๋ค. ํ ์ค๋ ๋๊ฐ ํฌ๋์ํ๋ฉด ๊ฒ์ ์ ์ฒด๊ฐ ์ฃฝ๋๋ค๋ ๋จ์ ์ด ์์ง๋ง, 60fps๋ผ๋ hard real-time ์๊ตฌ๊ฐ ๋ฉํฐ์ค๋ ๋๋ฅผ ๊ฐ์ ํฉ๋๋ค.
Q8. โ1:1 / N:1 / M:N ๋ชจ๋ธ์ด ๋ญ๊ฐ์?โ
์ฌ์ฉ์ ์ค๋ ๋์ ์ปค๋ ์ค๋ ๋๋ฅผ ์ด๋ป๊ฒ ๋งคํํ๋๋์ ๋ชจ๋ธ์ ๋๋ค. 1:1์ ์ฌ์ฉ์ ์ค๋ ๋ ํ๋์ ์ปค๋ ์ค๋ ๋ ํ๋๋ฅผ 1:1๋ก ๋์์ํค๋ ๋ฐฉ์์ผ๋ก, Linux pthreadยทWindows Threadยท
std::thread๊ฐ ๋ค 1:1์ ๋๋ค. ์์คํ ์ฝ ์ฐจ๋จ ์ ๊ทธ ์ค๋ ๋๋ง ์ํฅ์ ๋ฐ๊ณ ๋ฉํฐ ์ฝ์ด ํ์ฉ๋ ์์ฐ์ค๋ฝ์ง๋ง ์์ฑ ๋น์ฉ์ด ํฝ๋๋ค. N:1์ ์ฌ์ฉ์ ์ค๋ ๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ์ปค๋ ์ค๋ ๋ ํ๋์ ๋งคํํ๋๋ฐ, ๋งค์ฐ ๊ฐ๋ณ์ง๋ง ํ ์ค๋ ๋์ ์์คํ ์ฝ ์ฐจ๋จ์ผ๋ก ์ ๋ถ ๋ฉ์ถ๊ณ ๋ฉํฐ ์ฝ์ด๋ฅผ ๋ชป ์๋๋ค โ ๊ฑฐ์ ์ ์ฐ์ ๋๋ค. M:N์ ๋์ ์ ์ถฉ์ผ๋ก Go ๊ณ ๋ฃจํด์ด๋ Java Loom virtual thread๊ฐ M:N์ ๋๋ค. ์๋ง ๊ฐ ์ฌ์ฉ์ ์ค๋ ๋๋ฅผ ์ ์ ์์ ์ปค๋ ์ค๋ ๋ ์์์ ๋๋ฆฌ๋ ๋ชจ๋ธ์ ๋๋ค.
Q9. โshared_ptr์ ๋ฉํฐ์ค๋ ๋์์ ์์ ํ๊ฐ์?โ
์ฐธ์กฐ ์นด์ดํฐ ์์ฒด๋ atomic์ด๋ผ ์์ ํ์ง๋ง, shared_ptr์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด์ ๋ํ ๋์ ์ ๊ทผ์ ์์ ํ์ง ์์ต๋๋ค. 11๋ฒ์์ ์ ๋ฆฌํ ๊ทธ๋๋ก โ ์ ์ด ๋ธ๋ก์ reference count๋
std::atomic์ผ๋ก ์ฆ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ shared_ptr์ ๋ณต์ฌํ๊ฑฐ๋ ์๋ฉธ์์ผ๋ ์นด์ดํฐ๋ ์ ํํ๊ฒ ๊ด๋ฆฌ๋ฉ๋๋ค. ํ์ง๋ง shared_ptr์ด ๊ฐ๋ฆฌํค๋ ์ค์ ๊ฐ์ฒด ์์ฒด์ ๋ ์ค๋ ๋๊ฐ ๋์์ ์ฐ๋ฉด race condition์ ๋๋ค. ๊ทธ๋์ ๊ฐ์ฒด ์ ๊ทผ์ ๋ณ๋๋ก mutex๋ atomic์ผ๋ก ๋ณดํธํด์ผ ํฉ๋๋ค. atomic_load/store๊ฐ shared_ptr ์์ฒด์๋ ์์ด์ ๊ฐ์ ๋ณ์๋ฅผ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๊ฐ์์น์ฐ๋ ํจํด์ ๊ทธ๊ฑธ ์ธ ์ ์์ต๋๋ค.
Q10. โSTL ์ปจํ ์ด๋๋ thread-safeํ๊ฐ์?โ
๊ฐ๋ณ ์ปจํ ์ด๋๋ thread-safeํ์ง ์์ต๋๋ค. ํ์ค์ ๋ณด์ฅ์ โํ ์ปจํ ์ด๋์ const ๋ฉค๋ฒ ํจ์๋ ๋ค๋ฅธ ์ค๋ ๋์์ ๋์์ ํธ์ถํด๋ ์์ โ๊ณผ โ์๋ก ๋ค๋ฅธ ์ปจํ ์ด๋ ๊ฐ์ฒด๋ ๊ฐ์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์์ ๋กญ๊ฒ ์จ๋ ์์ โ ์ ๋์ ๋๋ค. ๊ฐ์ ์ปจํ ์ด๋์ ๋ ์ค๋ ๋๊ฐ ๋์์
push_back์ ํ๋ฉด race condition์ ๋๋ค. ๊ทธ๋์ 16๋ฒ์์ ์ ๋ฆฌํ ๋๋ก ๋ณดํธ๊ฐ ํ์ํ ๊ฒฝ์ฐ์ ์ธ๋ถ์์ mutex๋ก ๊ฐ์ธ๊ฑฐ๋, ๋ฝ-ํ๋ฆฌ๊ฐ ํ์ํ๋ฉดconcurrent_queue๊ฐ์ ๋์์ฑ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ก ์จ์ผ ํฉ๋๋ค. ์ธ๋ฆฌ์ผ์TQueue<T, EQueueMode::Mpsc>๊ฐ์ ๋ฝ-ํ๋ฆฌ ํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Q11. โfork()๋ ์ด๋ป๊ฒ ๋์ํ๋์?โ
fork()๋ ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ๋ณต์ ํด์ ์์ ํ๋ก์ธ์ค๋ฅผ ๋ง๋๋ ์์คํ ์ฝ์ ๋๋ค. ์์์ ๋ถ๋ชจ์ ๊ฑฐ์ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์ํ๋ก ์์ํ์ง๋ง, ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ด ๋ณ๊ฐ์ ๋๋ค. ํต์ฌ ์ต์ ํ๊ฐ Copy-On-Write(COW)์ ๋๋ค โ ์ฒ์์ ๋ถ๋ชจ์ ์์์ด ๊ฐ์ ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ๊ณต์ ํ๋ค๊ฐ, ์ด๋ ์ชฝ์ด๋ ๊ทธ ํ์ด์ง์ ์ฐ๊ธฐ๋ฅผ ์๋ํ๋ฉด ๊ทธ ์์ ์ OS๊ฐ ํ์ด์ง๋ฅผ ๋ณต์ฌํฉ๋๋ค. ๊ทธ๋์ fork ์งํ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฑฐ์ ์ ์ฐ๊ณ ๋น ๋ฆ ๋๋ค. ๊ทธ๋๋ ํ์ด์ง ํ ์ด๋ธยทPCBยทํธ๋ค ํ ์ด๋ธ ๋ณต์ฌ ๊ฐ์ ๊ณ ์ ๋น์ฉ์ด ์์ด์ ์ค๋ ๋ ์์ฑ๋ณด๋ค๋ ๋น์๋๋ค. Postgresยท์ ํต์ Apache๊ฐ fork ๋ชจ๋ธ์ ์ฐ๋ ์ด์ ๊ฐ ๊ฒฉ๋ฆฌ์ ์์ ์ฑ์ด๊ณ , fork ๋น์ฉ์ connection pooling์ผ๋ก ๊ฐ์ถฅ๋๋ค.
Q12. โFRunnable๊ณผ std::thread์ ์ฐจ์ด๋ ๋ญ๊ฐ์?โ
๋ณธ์ง์ ๊ฐ์ง๋ง ์ถ์ํ ์์ค์ด ๋ค๋ฆ ๋๋ค.
std::thread๋ OS ์ค๋ ๋๋ฅผ ์ง์ ๋ํํ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ณ ,FRunnable์ ์ธ๋ฆฌ์ผ์ด ๊ทธ ์์ ๋ง๋ ์์ปค ์ค๋ ๋ ์ถ์ํ์ ๋๋ค. ์ฐจ์ด๋ โ ๋ฉํฐ ํ๋ซํผ โFRunnable+FRunnableThread::Create๋ WindowsยทLinuxยท์ฝ์ ๊ตฌ๋ถ ์์ด ๋์, โก ๋ผ์ดํ์ฌ์ดํด ํ โInit(),Run(),Stop(),Exit()๊ฐ ํ์คํ๋ผ ์์ด์ cleanup ํจํด์ด ์ผ๊ด๋จ, โข UE์FCriticalSectionยทFEventยทFScopeLock๊ณผ ์์ฐ์ค๋ฝ๊ฒ ๊ฒฐํฉ. ์งง์ ์์ ์ด๋ผ๋ฉดFRunnable์ง์ ๋ง๋ค๊ธฐ๋ณด๋คAsyncTask๋ParallelFor๋ฅผ ์ฐ๋ ๊ฒ ๋ ํํฉ๋๋ค.
Q13. โ๋ฐ๋ณต์(iterator)์ ๋ฌดํจํ๋ ์ ์ผ์ด๋๊ณ ์ด๋ป๊ฒ ๋ฐฉ์งํ๋์?โ
๋ฐ๋ณต์ ๋ฌดํจํ๋ ์ปจํ ์ด๋ ๋ด๋ถ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์ด ๊ธฐ์กด iterator๊ฐ ๊ฐ๋ฆฌํค๋ ์์น๊ฐ ๋ ์ด์ ์ ํจํ์ง ์๊ฒ ๋๋ ํ์์ ๋๋ค. ์ปจํ ์ด๋ ์ข ๋ฅ๋ง๋ค ์ ์ฑ ์ด ๋ค๋ฆ ๋๋ค.
std::vectorโ ์ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ผ ๊ฐ์ฅ ์ทจ์ฝํฉ๋๋ค.push_back์ดcapacity๋ฅผ ์ด๊ณผํด ์ฌํ ๋น์ด ์ผ์ด๋๋ฉด ๋ชจ๋ iteratorยทํฌ์ธํฐยท์ฐธ์กฐ๊ฐ ๋ฌดํจํ๋ฉ๋๋ค. ์ค๊ฐerase/insert๋ ๊ทธ ์์น ์ดํ์ ๋ชจ๋ iterator๊ฐ ๋ฌดํจํ๋ฉ๋๋ค.
std::listโ ๋ ธ๋ ๊ธฐ๋ฐ์ด๋ผ ์์ ํ ํธ์ ๋๋ค.eraseํ ๋ ธ๋์ iterator๋ง ๋ฌดํจํ๋๊ณ , ๋ค๋ฅธ ๋ ธ๋์ iterator๋ ๊ทธ๋๋ก์ ๋๋ค.
std::map/std::set(RB-tree) โeraseํ ๋ ธ๋์ iterator๋ง ๋ฌดํจํ. ํธ๋ฆฌ ํ์ ์ด ์ผ์ด๋๋ ๋ค๋ฅธ ๋ ธ๋๋ ์์ ํฉ๋๋ค.
std::unordered_map/std::unordered_setโrehash(load factor ์ด๊ณผ)๊ฐ ์ผ์ด๋๋ฉด ๋ชจ๋ iterator๊ฐ ๋ฌดํจํ๋ฉ๋๋ค. ๋จ ํฌ์ธํฐ/์ฐธ์กฐ๋ ๊ทธ๋๋ก ์ ์ง๋๋ค๋ ์ ์ด vector์ ๋ค๋ฅธ ๋ฏธ๋ฌํ ์ฐจ์ด์ ๋๋ค.๋ฐฉ์ง ๋ฐฉ๋ฒ์ โ
reserve()๋ก capacity ๋ฏธ๋ฆฌ ํ๋ณด(vector), โกerase์ ๋ฆฌํด๊ฐ(๋ค์ ์ ํจ iterator)์ ๋ฐ๋์ ๋ฐ๊ธฐ โit = v.erase(it), โข โiterator ๋ณด๊ด ์ค์๋ ์ปจํ ์ด๋ ์์ ๊ธ์งโ ์์น, โฃ vector์์ ์ธ๋ฑ์ค ๊ธฐ๋ฐ ์ ๊ทผ์ผ๋ก ๋์ฒด ๊ฒํ . ์์ธํ ์ปจํ ์ด๋๋ณ ํ๋ 13๋ฒ(vector vs list), 14๋ฒ(map), 16๋ฒ(STL ์ปจํ ์ด๋ ํตํฉ)์ ์ ๋ฆฌ๋ผ ์์ต๋๋ค.
Q14. โ์คํ ์ค๋ฒํ๋ก(stack overflow)๋ ์ธ์ ๋ฐ์ํ๋์?โ
์คํ ์ค๋ฒํ๋ก๋ ์ค๋ ๋์ ์คํ ์์ญ์ด ํ๊ณ๋ฅผ ์ด๊ณผํด ๋ ์ด์ ํจ์ ํธ์ถ ํ๋ ์์ ์์ ์ ์์ ๋ ๋ฐ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ์ ๋๋ค.
์ฃผ์ ์์ธ ์ธ ๊ฐ์ง์ ๋๋ค โ ์ฒซ์งธ ๋ฌดํ ์ฌ๊ท ๋๋ ์ข ๋ฃ ์กฐ๊ฑด์ด ์๋ ์ฌ๊ท, ๋์งธ ๋๋ฌด ๊น์ ์ฌ๊ท(ํธ๋ฆฌ DFSยทnaive ํผ๋ณด๋์น ๋ฑ), ์ ์งธ ๊ฑฐ๋ํ ์ง์ญ ๋ณ์(
int arr[1000000]๊ฐ์ ๋์ฉ๋ ๋ฐฐ์ด์ ์คํ์ ์ก๋ ๊ฒฝ์ฐ).์คํ ํฌ๊ธฐ๋ OSยทํ๋ซํผ๋ณ๋ก ๋ค๋ฆ ๋๋ค โ Windows ๋ฉ์ธ ์ค๋ ๋ ๊ธฐ๋ณธ 1MB, Linux ๊ธฐ๋ณธ 8MB(
ulimit -s), ์์ปค ์ค๋ ๋๋ ๋ณดํต ๋ ์์ต๋๋ค(๋ณดํต 1~2MB). ์ธ๋ฆฌ์ผ์FRunnableThread::Create๋ ๊ธฐ๋ณธ 0์ด๋ฉด OS ๊ธฐ๋ณธ๊ฐ์ ์ฐ์ง๋ง ๋ช ์ ๊ฐ๋ฅํฉ๋๋ค.๋ฐ์ ์ Linux์์ SIGSEGV๋ก ํ๋ก์ธ์ค ์ข ๋ฃ, Windows์์
0xC00000FDSTATUS_STACK_OVERFLOW ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๊ฑด 19๋ฒ์์ ์ ๋ฆฌํ 4์์ญ ๋ชจ๋ธ์ Stack ์์ญ ํ๊ณ๊ฐ ๊ทธ๋๋ก ๋๋ฌ๋๋ ์ฌ๋ก๊ณ , ๊ทธ๋์ ํฐ ๋ฐ์ดํฐ๋ ์คํ ๋์ ํ(new/std::vector)์ ์ก๋ ๊ฒ ์์ ํฉ๋๋ค.
Q15. โ์ฌ๊ท๊ฐ ์ด๋ป๊ฒ ์คํ ์ค๋ฒํ๋ก๋ฅผ ์ผ์ผํค๋์? ํผ๋ณด๋์น๋ฅผ ์๋ก ๋ค๋ฉด?โ
์ฌ๊ท(recursion)๋ ํจ์๊ฐ ์๊ธฐ ์์ ์ ํธ์ถํ๋ ํจํด์ ๋๋ค. ํธ์ถ์ด ํ ๋ฒ ์ผ์ด๋ ๋๋ง๋ค ์คํ์ ์ ํจ์ ํ๋ ์์ด push๋ฉ๋๋ค. ์ข ๋ฃ ์กฐ๊ฑด(base case)์ด ์๊ฑฐ๋ ๊น์ด๊ฐ ๋๋ฌด ํฌ๋ฉด ์คํ์ ๋ค ์ฑ์ ์ค๋ฒํ๋ก๊ฐ ๋ฉ๋๋ค.
์ ํ์ ์ธ ์์๊ฐ naive ํผ๋ณด๋์น์ ๋๋ค.
1 2 3 4 int fib(int n) { if (n < 2) return n; // ์ข ๋ฃ ์กฐ๊ฑด return fib(n - 1) + fib(n - 2); // ์๊ธฐ ์์ ๋ ๋ฒ ํธ์ถ }
fib(40)์ ๋๋ง ํธ์ถํด๋ ํจ์ ํธ์ถ ํธ๋ฆฌ๊ฐ ์ฝ 10์ต ๋ฒ ํผ์ณ์ง๋ฉด์ ์๊ฐ ๋ณต์ก๋๊ฐ O(2^n)์ด ๋ฉ๋๋ค. ์คํ ๊น์ด๋ ์ต๋ n๊น์ง ๊ฐ๋๋ฐ, ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ๋ฐ๋ณต ๊ณ์ฐํ๋ ๊ฒ ๋ ํฐ ๋ฌธ์ ์ฃ .๋ง์ฝ ์ข ๋ฃ ์กฐ๊ฑด์ด ๋น ์ง๋ฉด(
if (n < 2) return n;์ ๊ฑฐ),fib(5) โ fib(4) โ fib(3) โ ...๋ก ์์๊น์ง ๋ฌดํํ ๋ด๋ ค๊ฐ์ ์คํ์ ๊ฐ๋ ์ฑ์ฐ๊ณ ์ฃฝ์ต๋๋ค โ ์ด๊ฒ โ์๊ธฐ๊ฐ ์๊ธฐ๋ฅผ ํธ์ถํ๋๋ฐ ๋ฉ์ถ ์ค ๋ชจ๋ฅด๋โ ๋ฌดํ ์ฌ๊ท์ ๋๋ค.ํด๊ฒฐ์ฑ ์ โ ๋ฉ๋ชจ์ด์ ์ด์ / DP โ ๊ฐ์ ๊ฐ์ ํ ๋ฒ๋ง ๊ณ์ฐํด ์บ์ฑ(O(n)์ผ๋ก ๋จ์ถ), โก ๋ฐ๋ณต๋ฌธ ๋ณํ โ for ๋ฃจํ๋ก ํ๋ฉด ์คํ ํ ํ๋ ์๋ง ์ฌ์ฉ, โข tail call optimization(TCO) โ ๋ง์ง๋ง์ ์๊ธฐ ํธ์ถ๋ง ๋จ๊ธฐ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ์ ํ๋ก ๋ณํํ ์ ์์ง๋ง C++ ํ์ค์์ ๋ณด์ฅํ์ง ์์(GCC/Clang ์ผ๋ถ ์ต์ ํ). ์์ ํ๊ฒ ์ฐ๋ ค๋ฉด ๋ฐ๋ณต๋ฌธ์ด๋ ๋ช ์์ ์คํ ์๋ฃ๊ตฌ์กฐ๋ก ํ์ด์ผ ํฉ๋๋ค.
Q16. โrace condition์ ์ ํํ ์ ์ํ๋ฉด? mutex์ spin lock์ ์ฐจ์ด๋?โ
Race condition์ ๋ ์ด์์ ์ค๋ ๋๊ฐ ๊ณต์ ๋ฐ์ดํฐ์ ๋์ ์ ๊ทผํ๋ฉด์ ์ ์ด๋ ํ๋๊ฐ ์ฐ๊ธฐ๋ฅผ ์ํํ ๋, ์คํ ์์(์ธํฐ๋ฆฌ๋น)์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋น๊ฒฐ์ ์ ์ผ๋ก ๋ฌ๋ผ์ง๋ ์ํ์ ๋๋ค.
counter++ํ ์ค๋ ์ฌ์ค์ loadยทaddยทstore 3๋จ๊ณ๋ผ ๋ ์ค๋ ๋๊ฐ ๋ผ์ด๋ค๋ฉด ๊ฐฑ์ ์์ค์ด ์ผ์ด๋๋ ๊ฒ ๋ํ ์ฌ๋ก์ ๋๋ค.ํด๊ฒฐ์ ํต์ฌ์ ์๊ณ ๊ตฌ์ญ(critical section)์ ํ ๋ฒ์ ํ ์ค๋ ๋๋ง ์คํํ๋๋ก ๋ณดํธํ๋ ๊ฒ์ด๊ณ , ๊ทธ ๋๊ตฌ๊ฐ mutex(์ํธ ๋ฐฐ์ ๋ฝ)์ ๋๋ค. ๊ทธ๋ฐ๋ฐ mutex์๋ ๋ ๊ฐ์ง ํฐ ๋ถ๋ฅ๊ฐ ์์ต๋๋ค.
std::mutex(sleeping mutex) โ ๋ฝ์ ๋ชป ์ก์ผ๋ฉด OS๊ฐ ๊ทธ ์ค๋ ๋๋ฅผ ๋ธ๋ก ์ํ๋ก ์ ํํ๊ณ ์ปจํ ์คํธ ์ค์์นญ์ ์ผ์ผ์ผ ๋ค๋ฅธ ์ค๋ ๋์ CPU๋ฅผ ๋๊น๋๋ค. ๋ฝ์ด ํ๋ฆฌ๋ฉด OS๊ฐ ๊นจ์์ค๋๋ค. ์๊ณ ๊ตฌ์ญ์ด ๊ธธ๊ฑฐ๋(์ ฮผs ์ด์) ๋ฝ ๊ฒฝํฉ์ด ์ ์ ๊ฒฝ์ฐ์ ์ ํฉํฉ๋๋ค. ์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ์ด 1~10ฮผs ๋ค์ง๋ง ๊ทธ ์๊ฐ ๋์ CPU๋ฅผ ๋ค๋ฅธ ์ผ์ ์ธ ์ ์๋ค๋ ๊ฒ ์ด๋์ด์ฃ .spin lock (์คํ๋ฝ) โ ๋ฝ์ ๋ชป ์ก์ผ๋ฉด CPU๋ฅผ ๋น๋น ๋๋ฉด์(busy-wait) ๋ฝ์ด ํ๋ฆฌ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ปจํ ์คํธ ์ค์์นญ์ด ์์ผ๋ ๋ฝ์ด ํ๋ฆฌ๋ ์ฆ์ ์ง์ ํฉ๋๋ค. ๋จ, CPU๋ฅผ ๊ทธ๋์ ๋ญ๋นํฉ๋๋ค. ์๊ณ ๊ตฌ์ญ์ด ๋งค์ฐ ์งง๊ณ (์์ญ ns~์ ฮผs) ๋ฉํฐ์ฝ์ด ํ๊ฒฝ์ผ ๋ ์ด๋์ ๋๋ค โ ์ปจํ ์คํธ ์ค์์นญ ๋น์ฉ๋ณด๋ค ์๊ณ ๊ตฌ์ญ์ด ์งง์ผ๋ฉด spin lock์ด ๋น ๋ฆ ๋๋ค. ๋จ์ผ ์ฝ์ด์์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ฝ์ ํ ๊ธฐํ ์์ฒด๊ฐ ์์ด์ ์ ๋ ์ฐ๋ฉด ์ ๋ฉ๋๋ค.
C++์์
std::mutex๋ ํ์ค์ด์ง๋ง spin lock์ ํ์ค์ ์๊ณstd::atomic_flag::test_and_set์ผ๋ก ์ง์ ๊ตฌํํ๊ฑฐ๋ OS API๋ฅผ ์๋๋ค. ์ธ๋ฆฌ์ผ์FCriticalSection(sleeping)๊ณผFSpinLock(์คํ)์ ๋ ๋ค ์ ๊ณตํฉ๋๋ค. ์ปค๋ ์ฝ๋์์ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ์ฒ๋ผ sleepํ ์ ์๋ ์ปจํ ์คํธ๊ฐ ์์ด์ spin lock์ด ํ์์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
Q17. โIPC๊ฐ ์ ํํ ๋ฌด์์ธ๊ฐ์?โ
IPC(Inter-Process Communication)๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฒฉ๋ฆฌ๋ ๋ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํ OS ์ฐจ์์ ๋ช ์์ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ํ๋ก์ธ์ค๋ ๊ฐ์ ๋ ๋ฆฝ๋ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๊ฐ์ง๋ ๊ทธ๋ฅ ๋ณ์๋ก๋ ํต์ ์ด ์ ๋๊ณ , OS๊ฐ ์ ๊ณตํ๋ ์ฑ๋์ ๊ฑฐ์ณ์ผ ํฉ๋๋ค.
์ฃผ์ ์ข ๋ฅ๋ ํ์ดํ(pipe), ๊ณต์ ๋ฉ๋ชจ๋ฆฌ(shared memory), ๋ฉ์์ง ํ(message queue), ์์ผ(socket), ์๊ทธ๋(signal), mmap(ํ์ผ ๋งคํ)์ ๋๋ค. ์๋์ ๊ฒฉ๋ฆฌ๋๊ฐ ๋ค๋ฆ ๋๋ค โ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋น ๋ฆ ๋๋ค(๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์๋ ๊ทธ๋๋ก), ๋ ํ๋ก์ธ์ค๊ฐ ๋ช ์์ ์ผ๋ก ๊ฐ์ ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ์๊ธฐ ๊ฐ์ ๊ณต๊ฐ์ ๋งคํํ๋ ๋ฐฉ์์ด๋ผ ํ ๋ฒ ์ค์ ํ๋ฉด ์ถ๊ฐ ๋น์ฉ์ด ๊ฑฐ์ ์์ต๋๋ค. ๋ฐ๋๋ก ์์ผ์ด ๊ฐ์ฅ ๋๋ฆฌ์ง๋ง(ํนํ TCP๋ ์ปค๋์ ๊ฑฐ์น๋ ์์ญ ฮผs ๋จ์) ๋ค๋ฅธ ๋จธ์ ๊ณผ๋ ํต์ ๊ฐ๋ฅํ ์ ์ฐ์ฑ์ด ์์ต๋๋ค.
ํต์ฌ์ IPC๊ฐ ๋น์ธ๋ค๋ ์ ์ ๋๋ค. ๊ทธ๋์ ๊ฒ์ ์์ง์ฒ๋ผ ๋งค ํ๋ ์ 16.6ms ์์ ์๋ง์ ๊ฐ์ฒด๋ฅผ ๋๊ธฐํํด์ผ ํ๋ ํ๊ฒฝ์์ ๋ฉํฐํ๋ก์ธ์ค + IPC๋ฅผ ์ธ ์ ์๊ณ , ๊ฐ์ ํ๋ก์ธ์ค ์์์ ๋ฉํฐ์ค๋ ๋ + ๊ณต์ ๋ฉ๋ชจ๋ฆฌ(์ค๋ ๋ ๊ฐ ์๋ ๊ณต์ )๋ฅผ ์ ํํ ์๋ฐ์ ์์ต๋๋ค. Chrome์ฒ๋ผ ๊ฒฉ๋ฆฌยท๋ณด์์ด ์ฐ์ ์ธ ์์ญ์์ IPC ๋น์ฉ์ ๊ฐ์ํ๊ณ ๋ฉํฐํ๋ก์ธ์ค๋ฅผ ์ฐ๋ ๊ฑฐ๊ณ ์. ๊ฒฉ๋ฆฌ๋ ๋น์ธ์ง๋ง ์์ , ๊ณต์ ๋ ๋น ๋ฅด์ง๋ง ์ํ โ ์ด ํธ๋ ์ด๋์คํ๊ฐ ํต์ฌ์ ๋๋ค.
Q18. โWindows ์์ ๊ด๋ฆฌ์์์ โํ๋ก์ธ์ค ์ด๋ฏธ์งโ๋ ๋ฌด์์ ์๋ฏธํ๋์?โ
โ์ด๋ฏธ์ง(Image)โ๋ ๋์คํฌ์ ์คํ ํ์ผ์ด ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋ ์ํ๋ฅผ ๊ฐ๋ฆฌํค๋ Windows ์ฉ์ด์ ๋๋ค. Windows ์คํ ํ์ผ์ PE(Portable Executable) ํฌ๋งท์ด๊ณ , ์ด๊ฒ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํ๋๋ฉด ๊ทธ๊ฑธ โํ๋ก์ธ์ค ์ด๋ฏธ์งโ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
์์ ๊ด๋ฆฌ์์์ ๋ณด์ด๋ ํญ๋ชฉ๋ค์ด ์ด ๊ฐ๋ ์ ์ง์ ๋๋ฌ๋ ๋๋ค โ Image Name(์:
chrome.exe)์ ๋์คํฌ์ ์คํ ํ์ผ๋ช ์ด๊ณ , Image Path๋ ๊ทธ ํ์ผ์ ๋์คํฌ ๊ฒฝ๋ก(C:\Program Files\...)์ ๋๋ค. ๋ ๊น์ด ๋ค์ด๊ฐ๋ฉด Image Base Address(๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์์ ์ฝ๋๊ฐ ๋ก๋๋๋ ์์ ์ฃผ์)๋ PE ํค๋์ ๋ช ์๋ผ ์์ต๋๋ค.์ค์ฉ์ ์ผ๋ก ์ค์ํ ์ฌ์ค ๋ ๊ฐ์ง โ ์ฒซ์งธ, ํ๋์ ์คํ ํ์ผ์ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์ธ ์ ์์ต๋๋ค. Chrome ํญ๋ง๋ค
chrome.exeํ๋ก์ธ์ค๊ฐ ๋์์ง๋ ๊ฒ ๊ทธ ์์์ธ๋ฐ, ๊ฐ ํ๋ก์ธ์ค๋ ๋ ๋ฆฝ๋ ๊ฐ์ ์ฃผ์ ๊ณต๊ฐ์ ๊ฐ์ง๋ง ์ฝ๋ ํ์ด์ง(read-only Text ์์ญ)๋ OS๊ฐ ๊ฐ์ ๋ฌผ๋ฆฌ ํ์ด์ง๋ฅผ ๊ณต์ ๋งคํํฉ๋๋ค. ๊ทธ๋์ ๊ฐ์ exe 100๊ฐ๋ฅผ ๋์๋ ์ฝ๋ ๋ฉ๋ชจ๋ฆฌ๋ ํ ๋ฒ๋ง ๋ญ๋๋ค.๋์งธ, Process Explorer(Sysinternals)๋
tasklist /v๋ช ๋ น์ผ๋ก ๋ ์์ธํ ์ด๋ฏธ์ง ์ ๋ณด(๋ก๋๋ DLL, Image Base, ํธ๋ค ์ ๋ฑ)๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ๋๋ฒ๊น ยท์ฑ๋ฅ ๋ถ์ํ ๋ ์์ฃผ ์ฐ๋ ๋๊ตฌ์ ๋๋ค. ํ๊ตญ์ด ์๋์ฐ ์์ ๊ด๋ฆฌ์์์ โ์ด๋ฏธ์ง ์ด๋ฆโ์ผ๋ก ๋ฒ์ญ๋ผ ์์ด์ ์ฒ์ ๋ณด๋ฉด ์ด์ํ์ง๋ง, ๋ณธ์ง์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋ ์คํ ํ์ผ์ ์ธ์คํด์ค๋ผ๋ ๋ป์ ๋๋ค.
Q19. โPCB๋ ์ปจํ ์คํธ ์ค์์นญ์์ ์ด๋ค ์ญํ ์ ํ๋์?โ
PCB(Process Control Block)๋ OS ์ปค๋์ด ํ๋ก์ธ์ค ํ๋๋น ํ๋์ฉ ์ ์งํ๋ ์ ๋ณด ์ ์ฅ ๊ตฌ์กฐ์ฒด์ ๋๋ค. ๋ค์ด์๋ ๊ฒ ๋ง์ต๋๋ค โ PID, ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด(ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค ์ฃผ์, ๋ฉ๋ชจ๋ฆฌ๋งต, ์ฝ๋/๋ฐ์ดํฐ/ํ ์์ญ ์ ๋ณด), ํธ๋ค ํ ์ด๋ธ(ํ์ผ ๋์คํฌ๋ฆฝํฐ, ์์ผ ๋ฑ), ์ค์ผ์ค๋ง ์ ๋ณด(์ฐ์ ์์, ์ํ โ Ready/Running/Wait), ๋ถ๋ชจ/์์ PID, ๊ทธ๋ฆฌ๊ณ ์์ ์ค๋ ๋๋ค์ TCB ๋ฆฌ์คํธ.
์ปจํ ์คํธ ์ค์์นญ์์ PCB๋ โํ๋ก์ธ์ค์ ๋ชจ๋ ์ํ๋ฅผ ์ ์ ๋ณด๊ดํด๋๋ ๋์ฅ๊ณ โ ์ญํ ์ ๋๋ค. ํ๋ฆ์ ์ด๋ ์ต๋๋ค โ โ ํ์ฌ ์คํ ์ค์ธ ํ๋ก์ธ์ค์ ๋ ์ง์คํฐ ์ปจํ ์คํธ(PCยทSPยท๋ฒ์ฉ ๋ ์ง์คํฐ)๋ฅผ PCB(์ ํํ๋ ๊ทธ ์์ TCB)์ ์ ์ฅ, โก OS ์ค์ผ์ค๋ฌ๊ฐ ๋ค์ ํ๋ณด ํ๋ก์ธ์ค ์ ํ, โข ๊ทธ ํ๋ก์ธ์ค์ PCB์์ ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค(CR3)ยทํธ๋ค ํ ์ด๋ธยท๋ ์ง์คํฐ๋ฅผ ๋ณต์, โฃ ์คํ ์ฌ๊ฐ.
ํต์ฌ์ ํ๋ก์ธ์ค ์ ํ์ด ๋น์ผ ์ด์ ๊ฐ PCB์ ๋ณต์ ํญ๋ชฉ์ด ๋ง๊ธฐ ๋๋ฌธ์ด๋ผ๋ ์ ์ ๋๋ค. ํ์ด์ง ํ ์ด๋ธ ๋ฒ ์ด์ค ๊ต์ฒด โ TLB flush โ ์บ์ cold โ ์งํ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ๋ชจ๋ ๋ฏธ์ค. ๋ฐ๋ฉด ์ค๋ ๋ ์ ํ์ ๊ฐ์ PCB ์์์ ๋ค๋ฅธ TCB๋ก ์ฎ๊ฒจ๊ฐ๋ ๊ฒ์ด๋ผ ํ์ด์ง ํ ์ด๋ธยทํธ๋ค์ ๊ทธ๋๋ก ๋๊ณ ๋ ์ง์คํฐ๋ง ๊ต์ฒดํฉ๋๋ค โ ๊ทธ๋์ 5~10๋ฐฐ ๋น ๋ฅธ ๊ฑฐ๊ณ ์. PCB์ TCB์ ํฌ๊ธฐ ์ฐจ์ด(PCB ์ KB / TCB ์๋ฐฑ ๋ฐ์ดํธ)๊ฐ ์ด ๋น์ฉ ์ฐจ์ด์ ์ง์ ์ ์์ธ์ ๋๋ค.
ํต์ฌ ์์ฝ ์นด๋ (์ฌ๊ฒ์ฌ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
ํ๋ก์ธ์ค = ์์ ์์ ๋จ์ (๋ฉ๋ชจ๋ฆฌยทํธ๋คยท๊ฐ์ ์ฃผ์ ๊ณต๊ฐ ๋
๋ฆฝ)
์ค๋ ๋ = ์คํ ํ๋ฆ ๋จ์ (์ฝ๋ยท๋ฐ์ดํฐยทํ ๊ณต์ , ์คํยท๋ ์ง์คํฐ๋ง ๋
๋ฆฝ)
์ฐจ์ด 3๊ฐ์ง:
โ ์์ ์์ โ ํ๋ก์ธ์ค ๋
๋ฆฝ / ์ค๋ ๋ ๊ณต์
โก ์ปจํ
์คํธ โ ํ๋ก์ธ์ค ๋น์(TLB flushยทํ์ด์ง ํ
์ด๋ธ ๊ต์ฒด) / ์ค๋ ๋ 5~10๋ฐฐ ๋น ๋ฆ
โข ํต์ โ IPC vs ๊ณต์ ๋ฉ๋ชจ๋ฆฌ (์๋์ ์์ ์ฑ ํธ๋ ์ด๋์คํ)
๋ฉ๋ชจ๋ฆฌ 4์์ญ:
Code (๊ณต์ ) / Data (๊ณต์ ) / Heap (๊ณต์ ) / Stack (์ค๋ ๋๋ณ ๋
๋ฆฝ)
PCB vs TCB:
PCB = ํ๋ก์ธ์ค ์ ๋ณด (PIDยทํ์ด์ง ํ
์ด๋ธยทํธ๋คยท๋ฉ๋ชจ๋ฆฌ๋งต) โ ํผ
TCB = ์ค๋ ๋ ์ ๋ณด (TIDยท๋ ์ง์คํฐยทSPยทPC) โ ์์
๋๊ธฐํ:
race condition โ ๋์ ์ ๊ทผ์ผ๋ก ๋น๊ฒฐ์ ์ ๊ฒฐ๊ณผ
mutex / atomic / condition_variable ๋ก ํด๊ฒฐ
RAII ๋ฝ: std::lock_guard / std::scoped_lock / FScopeLock (9๋ฒ RAII ํ๊ท)
deadlock 4์กฐ๊ฑด โ ์ํธ ๋ฐฐ์ ยท์ ์ ๋๊ธฐยท๋น์ ์ ยท์ํ ๋๊ธฐ
์ค๋ ๋ ๋ชจ๋ธ:
1:1 std::thread, pthread, Windows Thread (๊ฐ์ฅ ์ผ๋ฐ)
N:1 green thread (์ญ์ฌ์ )
M:N Go goroutine, Java Loom virtual thread (์ต์ )
์ ํ ๊ธฐ์ค:
๊ฒฉ๋ฆฌยท์์ ์ฑยท๋ณด์ โ ๋ฉํฐํ๋ก์ธ์ค (Chrome, Postgres)
์๋ยทํต์ ยท์์ ํจ์จ โ ๋ฉํฐ์ค๋ ๋ (๊ฒ์ ์์ง, ์์ปค ํ)
C++ API:
std::thread / std::jthread (C++20)
std::mutex + std::lock_guard / std::scoped_lock (C++17)
std::atomic<T>
std::async / std::future
std::condition_variable
์ธ๋ฆฌ์ผ:
๊ฒ์ ์ค๋ ๋ (Tick, UObject)
๋ ๋ ์ค๋ ๋ (RHI ๋ช
๋ น)
FRunnable + FRunnableThread โ std::thread ๋์
AsyncTask / ParallelFor โ ํ ๋์คํจ์น / ๋ณ๋ ฌ ๋ฃจํ
FCriticalSection + FScopeLock โ std::mutex + lock_guard ๋์
TAtomic / FEvent
check(IsInGameThread()) โ ์ค๋ ๋ ์์ ์๋ฐ ๊ฒ์ถ
๊ฒ์ ์์ง์ด ๋ฉํฐ์ค๋ ๋ ์ฐ๋ ์ด์ : 60fps (16.6ms/ํ๋ ์) โ IPC ๋น์ฉ ๋ชป ๊ฒฌ๋ค
ํ๊ท ๋ค๋ฆฌ โ ๋ค๋ฅธ CS ํ์ผ ์ฐ๊ฒฐ
| ํ์ผ | ์ฐ๊ฒฐ ์ง์ | |โ|โ| | 01_runtime | ๋ฉ๋ชจ๋ฆฌ 4์์ญ(Code/Data/Heap/Stack)์ด ๋ฉํฐ์ค๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ์ถ๋ฐ์ . Stack๋ง ์ค๋ ๋๋ณ ๋
๋ฆฝ, ๋๋จธ์ง๋ ๊ณต์ | | 03_new_vs_malloc | ํ ํ ๋น์ด ์ค๋ ๋ ๊ฐ ๊ณต์ ์์. new ์์ฒด๋ ์ค๋ ๋ ์์ (๋ณดํต)ํ์ง๋ง ํ ๋น๋ ๊ฐ์ฒด ์ ๊ทผ์ ๋๊ธฐํ ํ์ | | 09_rtti_raii | RAII๊ฐ mutex ๋ฝ์์๋ ๊ทธ๋๋ก โ std::lock_guard, std::scoped_lock, FScopeLock์ 9๋ฒ RAII์ ๋์์ฑ ์์ฉ | | 11_smart_pointer | shared_ptr ์ ์ด ๋ธ๋ก์ reference count๊ฐ atomic์ผ๋ก ๊ตฌํ๋จ. ์นด์ดํฐ๋ thread-safe, ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ ๋ณ๋ ๋ณดํธ ํ์ | | 16_stl_containers | STL ์ปจํ
์ด๋์ ์ค๋ ๋ ์์ ์ฑ ์ปจ๋ฒค์
โ ๊ฐ๋ณ ์ปจํ
์ด๋๋ thread-safeํ์ง ์์. ์ธ๋ถ mutex ๋๋ ๋์์ฑ ์๋ฃ๊ตฌ์กฐ ์ฌ์ฉ | | 18_list_sort | ์๊ณ ๋ฆฌ์ฆ ๋๋ฉ์ธ์ ๋ง์ง๋ง โ 19๋ฒ์์ OS ๋๋ฉ์ธ์ผ๋ก ์ ํ๋๋ ๋ถ๊ธฐ์ | ```