๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
CS/์šด์˜์ฒด์ œ

์Šค๋ ˆ๋“œ์™€ ์Šค๋ ˆ๋“œ ํ’€

by joaa 2024. 2. 13.

 

 

๐ŸŽˆ Hardware thread

์ฝ”์–ด(core)์˜ ๊ณ ๋ฏผ: ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ๊ฝค ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. 

 

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š”๊ฑด ์–ด๋–จ๊นŒ?

 

core: compute → memory → compute → memory

๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค core๋Š” ์‰ฌ๊ฒŒ ๋จ. 

 

ํ•˜๋‚˜์˜ core: compute → memory → compute → memory

                     memory → compute → memory → compute

๊ฐ๊ฐ์„ ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ๋ผ๊ณ  ์นญํ•จ. 

 

์ธํ…”์˜ hyper-threading

: ๋ฌผ๋ฆฌ์ ์ธ ์ฝ”์–ด๋งˆ๋‹ค ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋‘ ๊ฐœ

 

Hardware thread

: OS ๊ด€์ ์—์„œ๋Š” ๊ฐ€์ƒ์˜(logical) ์ฝ”์–ด

๋งŒ์•ฝ์— ์‹ฑ๊ธ€ ์ฝ”์–ด CPU์— ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋‘ ๊ฐœ๋ผ๋ฉด OS๋Š” ์ด CPU๋ฅผ ๋“€์–ผ ์ฝ”์–ด๋กœ ์ธ์‹ํ•˜๊ณ  ๋“€์–ผ ์ฝ”์–ด์— ๋งž์ถฐ์„œ OS ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ๋“ค์„ ์Šค์ผ€์ค„๋ง ํ•œ๋‹ค. 

 

Q. ์ธํ…” ๋“€์–ผ ์ฝ”์–ด CPU์— hyper-threading์ด ์ ์šฉ๋๋‹ค๋ฉด ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ๋Š” ์ด ๋ช‡ ๊ฐœ ์ธ๊ฐ€์š”?

4๊ฐœ. OS๋Š” CPU๋ฅผ 4์ฝ”์–ด๋กœ ์ธ์‹ํ•จ. 

 

 

 

์ปค๋„(kernel)

: ์šด์˜์ฒด์ œ์˜ ํ•ต์‹ฌ

: ์‹œ์Šคํ…œ์˜ ์ „๋ฐ˜์„ ๊ด€๋ฆฌ/๊ฐ๋…ํ•˜๋Š” ์—ญํ• 

: ํ•˜๋“œ์›จ์–ด์™€ ๊ด€๋ จ๋œ ์ž‘์—…์„ ์ง์ ‘ ์ˆ˜ํ–‰

 

๐ŸŽˆ OS Thread

: OS ์ปค๋„ ๋ ˆ๋ฒจ์—์„œ ์ƒ์„ฑ๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ์Šค๋ ˆ๋“œ

: CPU์—์„œ ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ๋‹จ์œ„, CPU ์Šค์ผ€์ค„๋ง์˜ ๋‹จ์œ„

: OS ์Šค๋ ˆ๋“œ์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์€ ์ปค๋„์ด ๊ฐœ์ž… → ๋น„์šฉ ๋ฐœ์ƒ

: ์‚ฌ์šฉ์ž ์ฝ”๋“œ์™€ ์ปค๋„ ์ฝ”๋“œ ๋ชจ๋‘ OS ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค

 

OS ์Šค๋ ˆ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•จ. 

- ๋„ค์ดํ‹ฐ๋ธŒ ์Šค๋ ˆ๋“œ, ์ปค๋„ ์Šค๋ ˆ๋“œ*, ์ปค๋„-๋ ˆ๋ฒจ ์Šค๋ ˆ๋“œ, OS-๋ ˆ๋ฒจ ์Šค๋ ˆ๋“œ

 

Q. OS ์Šค๋ ˆ๋“œ ์—ฌ๋Ÿ ๊ฐœ๊ฐ€ ํ•˜์ดํผ ์Šค๋ ˆ๋”ฉ์ด ์ ์šฉ๋œ ์ธํ…” ๋“€์–ผ์ฝ”์–ด ์œ„์—์„œ ๋™์ž‘ํ•œ๋‹ค๋ฉด OS ์Šค๋ ˆ๋“œ๋“ค์„ ์–ด๋–ป๊ฒŒ ์ฝ”์–ด์— ๊ท ๋“ฑํ•˜๊ฒŒ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

 

 

๋‹ค๋ฅธ ๋งฅ๋ฝ์—์„œ Kernel Thread

: OS ์ปค๋„์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ. 

  ์ฆ‰, ์ปค๋„ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์ปค๋„ ์Šค๋ ˆ๋“œ๋ผ๊ณ  ํ•˜๊ธฐ๋„ ํ•จ. 

 

 

๐ŸŽˆ User Thread

: ์Šค๋ ˆ๋“œ ๊ฐœ๋…์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ ˆ๋ฒจ์—์„œ ์ถ”์ƒํ™” ํ•˜๋‚˜ ๊ฒƒ

์œ ์ €-๋ ˆ๋ฒจ ์Šค๋ ˆ๋“œ๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•จ.

 

Thread thread = new Thread();

thread.start(); // OS ์‹œ์Šคํ…œ ์ฝœ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ OS ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ

 

์œ ์ € ์Šค๋ ˆ๋“œ๊ฐ€ CPU์—์„œ ์‹คํ–‰๋˜๋ ค๋ฉด OS ์Šค๋ ˆ๋“œ์™€ ๋ฐ˜๋“œ์‹œ ์—ฐ๊ฒฐ๋ผ์•ผ ํ•œ๋‹ค. 

 

๊ทธ๋ ‡๋‹ค๋ฉด ์œ ์ € ์Šค๋ ˆ๋“œ์™€ OS ์Šค๋ ˆ๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ์‹œํ‚ฌ ๊ฒƒ์ธ๊ฐ€?

1. One-to-One model (์ž๋ฐ”๊ฐ€ ์ฑ„ํƒ)

์œ ์ € ์Šค๋ ˆ๋“œ์™€ OS ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ๋Œ€์ผ๋กœ ์—ฐ๊ฒฐ๋จ. 

์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ๋ฅผ OS์— ์œ„์ž„, ์Šค์ผ€์ค„๋ง๋„ ์ปค๋„์ด ์ˆ˜ํ–‰.

์œ ์ € ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™˜๊ฒฝ์„ ์ž˜ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ. 

ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋ฝ ์ƒํƒœ์—ฌ๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•จ. 

์ผ๋Œ€์ผ ๋งคํ•‘ ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— race condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ. 

 

2. Many-to-One model

์œ ์ € ์Šค๋ ˆ๋“œ ์—ฌ๋Ÿฌ๊ฐœ์™€ OS ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ ํ•˜๋‚˜์— ์—ฐ๊ฒฐ๋จ. 

์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ์œ ์ € ๋ ˆ๋ฒจ์—์„œ๋งŒ ์ด๋ฃจ์–ด์ง€๊ณ  ์ปค๋„์ด ๊ฐœ์ž…ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋” ๋น ๋ฆ„. 

์œ ์ € ์Šค๋ ˆ๋“œ ๊ฐ™์˜ ์Šค์œ„์นญ์ด one-to-one ๋ชจ๋ธ๋ณด๋‹ค ๋น ๋ฆ„. 

OS ๋ ˆ๋ฒจ์—์„œ race condition ๊ฐ€๋Šฅ์„ฑ์ด ์ ๋‹ค. 

OS ์Šค๋ ˆ๋“œ ํ•˜๋‚˜์ด๋ฏ€๋กœ ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™˜๊ฒฝ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†์Œ. 

ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋ฝ → ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋“ค์ด ๋ธ”๋ฝ => ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด non block I/O ์‚ฌ์šฉํ•จ.

 

3. Many-to-Many model

์œ ์ € ์Šค๋ ˆ๋“œ๋“ค์ด ์ ์ ˆํ•œ ๊ฐœ์ˆ˜์˜ OS ์Šค๋ ˆ๋“œ์— ์—ฐ๊ฒฐ๋จ. 

์œ ์ € ์Šค๋ ˆ๋“œ๊ฐ„์˜ ์Šค์œ„์นญ์ด ๋น ๋ฅด๋ฉด์„œ ๋ฉ€ํ‹ฐ ์ฝ”์–ด๋ฅผ ํ™œ์šฉ, 

ํ•˜๋‚˜๋ฅผ ๋ธ”๋Ÿญํ•ด๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋Ÿญ ๋˜์ง€ ์•Š์Œ. 

๊ตฌํ˜„์ด ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ .

 

 

๋‹ค๋ฅธ ์˜๋ฏธ์˜ User Thread

OS์™€๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ € ๋ ˆ๋ฒจ์—์„œ ์Šค์ผ€์ค„๋ง๋˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์œ ์ € ์Šค๋ ˆ๋“œ๋ผ๊ณ  ํ•˜๊ธฐ๋„ ํ•จ. 

 

 

 

 

 

๐ŸŽˆ Green Thread

Java ์ดˆ์ฐฝ๊ธฐ ๋ฒ„์ „์€ Many-to-One ์Šค๋ ˆ๋”ฉ ๋ชจ๋ธ์„ ์‚ฌ์šฉ. ์ด ๋•Œ ์ด ์œ ์ € ์Šค๋ ˆ๋“œ๋“ค์„ ๊ทธ๋ฆฐ ์Šค๋ ˆ๋“œ๋ผ๊ณ  ์นญํ•จ.

OS์™€๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ € ๋ ˆ๋ฒจ์—์„œ ์Šค์ผ€์ค„๋ง๋˜๋Š” ์Šค๋ ˆ๋“œ.

๋งฅ๋ฝ์— ๋”ฐ๋ผ ์œ ์ € ์Šค๋ ˆ๋“œ = ๊ทธ๋ฆฐ ์Šค๋ ˆ๋“œ.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

๐ŸŽˆ ์Šค๋ ˆ๋“œ ํ’€

 

API ์š”์ฒญ ๋ฐฉ์‹ ์ค‘ Thread per request model์ด ์žˆ์Œ. 

: request๋งˆ๋‹ค thread๋ฅผ ํ•˜๋‚˜์”ฉ ํ• ๋‹นํ•ด์„œ ํ•˜๋‚˜์˜ request๋ฅผ ํ•˜๋‚˜์˜ thread๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ. 

 

 

๋งŒ์•ฝ thread per request ๋ชจ๋ธ์˜ ๋™์ž‘ ๋ฐฉ์‹์ด

์„œ๋ฒ„์— ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ๋งˆ๋‹ค ์Šค๋ ˆ๋“œ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์„œ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚œ ์Šค๋ ˆ๋“œ๋Š” ๋ฒ„๋ฆฌ๋Š” ์‹์œผ๋กœ ๋™์ž‘

ํ•œ๋‹ค๋ฉด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋Š”๊ฐ€??

 

• ์Šค๋ ˆ๋“œ ์ƒ์„ฑ์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„ ๋•Œ๋ฌธ์— ์š”์ฒญ ์ฒ˜๋ฆฌ๊ฐ€ ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆผ.

 

• ์ฒ˜๋ฆฌ ์†๋„๋ณด๋‹ค ๋” ๋น ๋ฅด๊ฒŒ ์š”์ฒญ์ด ๋Š˜์–ด๋‚˜๋ฉด

  → ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์† ์ƒ์„ฑ(์Šค๋ ˆ๋“œ ์ˆ˜ ์ฆ๊ฐ€)

  →  ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋” ์ž์ฃผ ๋ฐœ์ƒ

  →  CPU ์˜ค๋ฒ„ํ—ค๋“œ ์ฆ๊ฐ€๋กœ CPU time ๋‚ญ๋น„→

  →  ์„œ๋ฒ„ ์ „์ฒด๊ฐ€ ์‘๋‹ต ๋ถˆ๊ฐ€๋Šฅ ์ƒํƒœ์— ๋น ์ง

 

• ์ฒ˜๋ฆฌ ์†๋„๋ณด๋‹ค ๋” ๋น ๋ฅด๊ฒŒ ์š”์ฒญ์ด ๋Š˜์–ด๋‚˜๋ฉด

  →  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์† ์ƒ์„ฑ(์Šค๋ ˆ๋“œ ์ˆ˜ ์ฆ๊ฐ€)

  →  ๋ฉ”๋ชจ๋ฆฌ ๊ณ ๊ฐˆ

 

 

 

๋ฏธ๋ฆฌ ์Šค๋ ˆ๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด ๋†“๊ณ  ์žฌ์‚ฌ์šฉ → ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ์‹œ๊ฐ„ ์ ˆ์•ฝ

์ œํ•œ๋œ ๊ฐœ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์šด์šฉ → ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฌด์ œํ•œ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€

 

Thread pool ์‚ฌ๋ก€: ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋•Œ

•  thread per request ๋ชจ๋ธ

•  task๋ฅผ subtask๋กœ ๋‚˜๋‰˜์–ด์„œ ๋™์‹œ์— ์ฒ˜๋ฆฌ

•  ์ˆœ์„œ ์ƒ๊ด€์—†์ด ๋™์‹œ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ task ์ฒ˜๋ฆฌ

 

 

Thread pool ์‚ฌ์šฉ ํŒ

1. ์Šค๋ ˆ๋“œ ํ’€์— ๋ช‡ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ ์ ˆํ•œ๊ฐ€?

   CPU ์ฝ”์–ด ๊ฐœ์ˆ˜์˜ task์˜ ์„ฑํ–ฅ์— ๋”ฐ๋ผ ๋‹ค๋ฆ„. 

   CPU-bound task๋ผ๋ฉด ์ฝ”์–ด ๊ฐœ์ˆ˜ ๋งŒํผ ํ˜น์€ ๋ช‡ ๊ฐœ ๋” ๋งŽ์€ ์ •๋„

   I/O-bound task๋ผ๋ฉด ์ฝ”์–ด ๊ฐœ์ˆ˜๋ณด๋‹ค 1.5๋ฐฐ? ๋‘ ๋ฐฐ? ์„ธ ๋ฐฐ? ๊ฒฝํ—˜์ ์œผ๋กœ ์ฐพ์•„์•ผ ํ•จ. 

2. ์Šค๋ ˆ๋“œ ํ’€์—์„œ ์‹คํ–‰๋  task ๊ฐœ์ˆ˜์— ์ œํ•œ์ด ์—†๋‹ค๋ฉด

   ์Šค๋ ˆ๋“œ ํ’€์˜ ํ์— ์‚ฌ์ด์ฆˆ ์ œํ•œ์„ ํ™•์ธํ•  ๊ฒƒ!

 

 

์ž๋ฐ”์˜ Executors ํด๋ž˜์Šค

static ๋ฉ”์„œ๋“œ๋กœ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์Šค๋ ˆ๋“œ ํ’€์„ ์ œ๊ณต

ExecuterService threadPool = Executors.newFixedThreadPool(10);

threadPool.submit(task1);

threadPool.submit(task2);

=> Queue size์— int max_val์ด ๋“ค์–ด๊ฐ”์œผ๋ฏ€๋กœ ์Šค๋ ˆ๋“œ ํ’€์— ์š”์ฒญ์ด ๋งŽ์•„์ง€๋ฉด ํ์— ๊ณ„์† ์Œ“์ผ ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜ ์š”์ธ์ด ์žˆ๋‹ค. 

     ์‚ฌ์ด์ฆˆ ์ œํ•œ์ด ์—†๋Š” ํ๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ ๊ฐˆ์‹œํ‚ค๋Š” ์ž ์žฌ์  ์œ„ํ—˜ ์š”์ธ์ด ๋  ์ˆ˜ ์žˆ๋‹ค. 

     ํ๊ฐ€ ๋‹ค ์ฐจ๋ฉด ์ดํ›„์˜ ์š”์ฒญ์„ ๋ฒ„๋ฆฌ๋”๋ผ๋„ ์ „์ฒด ์‹œ์Šคํ…œ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•จ. 

 

 

pool์ด๋ผ๋Š” ๊ฐœ๋…์ด ์Šค๋ ˆ๋“œ์—๋งŒ ์“ฐ์ด๋Š” ๊ฒƒ์€ ์•„๋‹˜. 

connection pool, process pool, ...

CPU bound ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ๋Š” process pool์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

์ถœ์ฒ˜: ์Šค๋ ˆ๋“œ ์ข…๋ฅ˜๊ฐ€ ์ฐธ ๋งŽ์ฃ ? ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ, OS ์Šค๋ ˆ๋“œ, ๋„ค์ดํ‹ฐ๋ธŒ ์Šค๋ ˆ๋“œ, ์ปค๋„ ์Šค๋ ˆ๋“œ, ์œ ์ € ์Šค๋ ˆ๋“œ, ๊ทธ๋ฆฐ ์Šค๋ ˆ๋“œ๊นŒ์ง€ ํ•œ๋ฒˆ์— ์ •๋ฆฌํ•ด์„œ ์•Œ๋ ค๋“œ๋ฆฝ๋‹ˆ๋‹ค!! (youtube.com)