๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ๊ณผ ์„ฑ๋Šฅ


ํ•œ ๊ฐ€๊ฒŒ์— ์ง์›์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ๊ฐ€๊ฒŒ๋Š” ๋” ๋นจ๋ฆฌ ๋Œ์•„๊ฐˆ๊นŒ?

์ง๊ด€์ ์œผ๋กœ๋Š” ๊ทธ๋ ‡๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์ง์›์ด ๋„ˆ๋ฌด ๋งŽ์•„์ง€๋ฉด ์˜คํžˆ๋ ค ์„œ๋กœ ๋™์„ ์ด ๊ผฌ์ด๊ณ 
๋ˆ„๊ฐ€ ์–ด๋–ค ์ผ์„ ํ•˜๋Š”์ง€ ํ˜ผ๋ž€์ด ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ๋‹ค.

์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋„ ๋น„์Šทํ•œ ์ผ์ด ๋ฐœ์ƒํ•œ๋‹ค.

์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ(Multithreading)์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๊ฐ€ ๋งŽ๋‹ค๊ณ  ํ•ด์„œ ํ•ญ์ƒ ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์ด ์ข‹์•„์ง€๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์ด ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ์ƒํ™ฉ์—์„œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์ด ํšจ๊ณผ์ ์ธ์ง€ ์‚ดํŽด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.


๋™๊ธฐํ™” ๋น„์šฉ (Synchronization Cost)


๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ์•ˆ์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์„œ๋กœ ๊ณต์œ ํ•œ๋‹ค.
์ด ๊ตฌ์กฐ ๋•๋ถ„์— ์Šค๋ ˆ๋“œ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ ๊ฐ€ ์‰ฝ๊ณ  ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ€๋ณ๋‹ค.

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์—๋Š” ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ „์—ญ ๋ณ€์ˆ˜๋‚˜ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋™์‹œ์— ์ˆ˜์ •ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐ์ดํ„ฐ ๊ฐ’์ด ๊ผฌ์ด๊ฑฐ๋‚˜ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ ์˜์—ญ์„ ์ž„๊ณ„ ์˜์—ญ(Critical Section)์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ๊ณผ ์ •ํ™•์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋™๊ธฐํ™”(Synchronization) ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๋™๊ธฐํ™” ๊ธฐ๋ฒ•์—๋Š” ๋Œ€ํ‘œ์ ์œผ๋กœ ๋ฎคํ…์Šค(Mutex) ๋‚˜ ์„ธ๋งˆํฌ์–ด(Semaphore)์ด ์žˆ๋‹ค.

์ด๋“ค์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋„๋ก ์ œํ•œํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฌธ์ œ๋Š” ์—ฌ๊ธฐ์„œ ๋๋‚˜์ง€ ์•Š๋Š”๋‹ค.

๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Lock์€ ๊ณต์œ  ์ž์›์„ ๋ณดํ˜ธํ•ด ์ฃผ์ง€๋งŒ, ๋™์‹œ์— ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณ‘๋ ฌ์„ฑ์„ ์ œํ•œํ•˜๋Š” ์š”์†Œ๊ฐ€ ๋˜๊ธฐ๋„ ํ•œ๋‹ค.

์Šค๋ ˆ๋“œ๋Š” ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๊ธฐ์œ„ํ•ด Lock ํš๋“, ์ž‘์—… ์ˆ˜ํ–‰, Lock ํ•ด์ œ์™€ ๊ฐ™์€ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.
์ด๋•Œ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ Lock์„ ์žก๊ณ  ์žˆ๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์€ ํ•ด๋‹น ์ž์›์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋Œ€๊ธฐ ์ƒํƒœ์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์„ Lock ๊ฒฝ์Ÿ(Contention)์ด๋ผ๊ณ  ํ•œ๋‹ค.

์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ์ž์›์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด์„œ Lock ๊ฒฝ์Ÿ๊ณผ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ์ ์  ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์‹ค์ œ๋กœ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์™€ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ž˜์„œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋‹จ์ˆœํžˆ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŽ์ด ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ณต์œ  ์ž์›์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ์ž„๊ณ„ ์˜์—ญ์„ ์ตœ๋Œ€ํ•œ ์งง๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

๋ฌผ๋ก  ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ •๋‹ต์€ ์•„๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” ์—ฌ์ „ํžˆ CPU ์ฝ”์–ด๋ฅผ ๋™์‹œ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ์ƒํ™ฉ์—์„œ ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ ์ค‘์š”ํ•œ ์ ์€ ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ๋ฌด์ž‘์ • ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ตฌ์กฐ์™€ ์ž‘์—… ํŠน์„ฑ์— ๋งž๊ฒŒ ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.


Context Switching ์˜ค๋ฒ„ํ—ค๋“œ


์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด CPU๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ๋ฒˆ๊ฐˆ์•„ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

์ด ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋น„์šฉ์ด Context Switching ์˜ค๋ฒ„ํ—ค๋“œ์ด๋‹ค.

Context Switching์€ ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ 
๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ž‘์—…์„ ์˜๋ฏธํ•œ๋‹ค.

์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋Š” ์‹คํ–‰ ํ๋ฆ„์ด ํ•˜๋‚˜๋ฟ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์ „ํ™˜์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก
CPU๊ฐ€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ„์† ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

ํŠนํžˆ CPU ์ฝ”์–ด ์ˆ˜๋ณด๋‹ค ํ›จ์”ฌ ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด
CPU๋Š” ์‹ค์ œ ์ž‘์—…๋ณด๋‹ค ์Šค๋ ˆ๋“œ ์ „ํ™˜์— ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด 1๋ถ€ํ„ฐ 1000๊นŒ์ง€ ๋ง์…ˆ์„ ํ•˜๋Š” ์ž‘์—…์„ 100๋ฒˆ ์ˆ˜ํ–‰ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํžˆ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

long sum = 0; 
for(int j=0; j<100; j++) {
  for(int i=0; i<1000; i++) {
    sum += i;  
  } 
}

์ด ์ฝ”๋“œ๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๋ฐ˜๋ฉด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ ์ž‘์—…์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋กœ ๋‚˜๋ˆ„์–ด ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

long sum = 0; 

/*  ์Šค๋ ˆ๋“œ 1 */
new Thread(() -> {
    for (int i = 0; i < 10000000; i++) {
        sum += i;
    }
}).start();

/*  ์Šค๋ ˆ๋“œ 2 */
new Thread(() -> {
    for (int i = 0; i < 10000000; i++) {
        sum += i;
    }
}).start();

// ... ์Šค๋ ˆ๋“œ 3~99 ...

/*  ์Šค๋ ˆ๋“œ 100 */
new Thread(() -> {
    for (int i = 0; i < 10000000; i++) {
        sum += i;
    }
}).start();

์ง๊ด€์ ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” 100๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅผ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก CPU๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฒˆ๊ฐˆ์•„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๊ณ  ๊ทธ ๊ณผ์ •์—์„œ Context Switching์ด ๊ณ„์† ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

์ด ์ „ํ™˜ ๊ณผ์ •์—์„œ๋„ CPU ์‹œ๊ฐ„๊ณผ ์ž์›์ด ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ๋Š” ์‹ค์ œ ๊ณ„์‚ฐ ์ž‘์—…๋ณด๋‹ค ์Šค๋ ˆ๋“œ ์ „ํ™˜ ๋น„์šฉ์ด ๋” ์ปค์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.

์ฆ‰ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ํ•ญ์ƒ ์„ฑ๋Šฅ์ด ์„ ํ˜•์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
โ€œ์Šค๋ ˆ๋“œ๊ฐ€ ๋งŽ์„์ˆ˜๋ก ์ž‘์—…์„ ๋ถ„๋ฆฌํ•ด์„œ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋‹ˆ๊นŒ ํ•ญ์ƒ ๋น ๋ฅด๋‹คโ€๋Š” ๊ณ ์ •๊ด€๋…์€ ํ‹€๋ ธ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

ํŠนํžˆ CPU ์ฝ”์–ด ์ˆ˜๋ณด๋‹ค ํ›จ์”ฌ ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด CPU๋Š” ๊ณ„์† ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ์‹คํ–‰ํ•ด์•ผ ํ•˜๊ณ 
์ด๋กœ ์ธํ•ด ์˜คํžˆ๋ ค ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” CPU ์ฝ”์–ด ์ˆ˜์— ๋งž๋Š” ์ ์ ˆํ•œ ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.


Thread Pool


๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ํ•ญ์ƒ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์„ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
์„œ๋น„์Šค๊ฐ€ ํ•œ์‚ฐํ•œ ์‹œ๊ฐ„์—๋Š” ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋ฌด ์ž‘์—…๋„ ํ•˜์ง€ ์•Š๊ณ  ๋Œ€๊ธฐ ์ƒํƒœ์— ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐ ์ƒํƒœ๋ผ๊ณ  ํ•ด์„œ ์•„๋ฌด ์ž์›๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ๋Š” ์กด์žฌ ์ž์ฒด๋งŒ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ, CPU ์Šค์ผ€์ค„๋ง ์ž์›์„ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ๋„ˆ๋ฌด ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด๋ถˆํ•„์š”ํ•œ ์ž์› ๋‚ญ๋น„๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด Thread Pool์ด๋‹ค.

Thread Pool์€ ๋ง ๊ทธ๋Œ€๋กœ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘” ์Šค๋ ˆ๋“œ๋“ค์˜ ์ง‘ํ•ฉ์ด๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋  ๋•Œ ์ผ์ • ๊ฐœ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด ๋‘๊ณ , ์ž‘์—…์ด ๋ฐœ์ƒํ•˜๋ฉด ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๋งฅ๋„๋‚ ๋“œ ๋น„์œ ๋กœ ๋‹ค์‹œ ์ƒ๊ฐํ•ด๋ณด์ž.

์†๋‹˜์ด ์˜ฌ ๋•Œ๋งˆ๋‹ค ์ง์›์„ ์ƒˆ๋กœ ๋ฝ‘๋Š”๋‹ค๋ฉด ์ฑ„์šฉ ๊ณผ์ •๋งŒ์œผ๋กœ๋„ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆด ๊ฒƒ์ด๋‹ค.
๊ทธ๋ž˜์„œ ๋ณดํ†ต์€ ์ ๋‹นํ•œ ์ˆ˜์˜ ์ง์›์ด ํ•ญ์ƒ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ์†๋‹˜์ด ์˜ค๋ฉด ๋ฐ”๋กœ ์ผ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

Thread Pool๋„ ๊ฐ™์€ ๊ฐœ๋…์ด๋‹ค.

ํ•„์š”ํ•œ ๋งŒํผ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘๊ณ  ์ž‘์—…์ด ์ƒ๊ธธ ๋•Œ ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์›น ์„œ๋ฒ„๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž. ์‚ฌ์šฉ์ž ์š”์ฒญ์ด ๋™์‹œ์— ๋งŽ์ด ๋“ค์–ด์˜ฌ ๋•Œ ์„œ๋ฒ„๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

์ด๋•Œ ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์„ฑ๋Šฅ์— ๋ถ€๋‹ด์ด ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Thread Pool์„ ์‚ฌ์šฉํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

from concurrent.futures import ThreadPoolExecutor
import time

# ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
def handle_request(user_id):
    print(f"์‚ฌ์šฉ์ž {user_id} ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ์ž‘")
    
    # ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ 2์ดˆ ๊ฑธ๋ฆฐ๋‹ค๊ณ  ๊ฐ€์ •
    time.sleep(2)
    
    print(f"์‚ฌ์šฉ์ž {user_id} ์š”์ฒญ ์ฒ˜๋ฆฌ ์™„๋ฃŒ")

# ์ตœ๋Œ€ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง„ Thread Pool ์ƒ์„ฑ
with ThreadPoolExecutor(max_workers=3) as executor:

    # ์‚ฌ์šฉ์ž 5๋ช…์ด ๋™์‹œ์— ์š”์ฒญํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •
    for user in range(1, 6):
        executor.submit(handle_request, user)

์ด ์ฝ”๋“œ์—์„œ๋Š” 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ Thread Pool์„ ๋งŒ๋“ค๊ณ  5๊ฐœ์˜ ์ž‘์—…์„ ์‹คํ–‰ํ•œ๋‹ค.

Thread 1 โ†’ ์‚ฌ์šฉ์ž 1 ์š”์ฒญ ์ฒ˜๋ฆฌ
Thread 2 โ†’ ์‚ฌ์šฉ์ž 2 ์š”์ฒญ ์ฒ˜๋ฆฌ
Thread 3 โ†’ ์‚ฌ์šฉ์ž 3 ์š”์ฒญ ์ฒ˜๋ฆฌ

์š”์ฒญ์ด ๋๋‚˜๋ฉด ๊ธฐ์กด ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•ด ๋‹ค์Œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ

Thread 1 โ†’ ์‚ฌ์šฉ์ž 4 ์š”์ฒญ ์ฒ˜๋ฆฌ
Thread 2 โ†’ ์‚ฌ์šฉ์ž 5 ์š”์ฒญ ์ฒ˜๋ฆฌ

์Šค๋ ˆ๋“œ๋ฅผ ๊ณ„์† ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ธฐ์กด ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ฉฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์‹์œผ๋กœ ๋™์ž‘์„ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋งŒ์•ฝ Thread Pool์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์‚ฌ์šฉ์ž ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ„์† ์ƒ์„ฑํ•˜๊ณ  ์ œ๊ฑฐํ•˜๋Š” ์ž‘์—…์€ ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ๋น„์šฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ์‹ค์ œ ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์œ„์™€ ๊ฐ™์ด Thread Pool ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.


CPU Bound vs I/O Bound


๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์˜ ํšจ๊ณผ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๊ฒฉ์— ๋”ฐ๋ผ ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง„๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ CPU Bound์™€ I/O Bound ๋‘ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

์šฐ์„  CPU Bound๋Š” CPU ์—ฐ์‚ฐ์— ์˜์กดํ•˜๋Š” ์ž‘์—…. ์ฆ‰ CPU ๊ณ„์‚ฐ์ด ๋Œ€๋ถ€๋ถ„์ธ ์ž‘์—…์ด๋‹ค.

์˜์ƒ์ฒ˜๋ฆฌ, ๋ฐ์ดํ„ฐ ๋ถ„์„, ์•”ํ˜ธํ™” ์—ฐ์‚ฐ ๋“ฑ์ด ์žˆ๋Š”๋ฐ ์ด ๊ฒฝ์šฐ ์Šค๋ ˆ๋“œ๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์ƒ์„ฑํ•˜๋ฉด CPU๊ฐ€ ๊ณ„์† ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ”๊พธ๋А๋ผ ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ณดํ†ต ์Šค๋ ˆ๋“œ ์ˆ˜(์Šค๋ ˆ๋“œ ์ˆ˜ โ‰ˆ CPU ์ฝ”์–ด ์ˆ˜)๊ฐ€ ์ ์ ˆํ•˜๋‹ค๊ณ  ์•Œ๋ ค์ ธ ์žˆ๋‹ค.

I/O Bound๋Š” ์ž…์ถœ๋ ฅ ์ž‘์—…์ด ๋งŽ์€ ํ”„๋กœ๊ทธ๋žจ, ์ฆ‰ I/O ์žฅ์น˜์˜ ์‘๋‹ต ์†๋„์— ์˜์กดํ•˜๋Š” ์ž‘์—…์„ ๋งํ•œ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ๋Š” ์›น ์„œ๋ฒ„, ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์š”์ฒญ๊ณผ ๊ฐ™์€ ์ž‘์—…์ด ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ž‘์—…๋“ค์€ ๋Œ€๋ถ€๋ถ„ CPU ์—ฐ์‚ฐ๋ณด๋‹ค ์ž…์ถœ๋ ฅ ์žฅ์น˜์˜ ์‘๋‹ต ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๋Š” ์ž‘์—…์€ ๋””์Šคํฌ ์ ‘๊ทผ์ด๋‚˜ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— CPU ๊ณ„์‚ฐ๋ณด๋‹ค ํ›จ์”ฌ ๋А๋ฆฌ๋‹ค.

์ด๋•Œ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋ฉด ์ž…์ถœ๋ ฅ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ CPU๋Š” ๋‹ค์Œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋Œ€๊ธฐ ์ƒํƒœ(Blocked)์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. ์ฆ‰ ํ”„๋กœ๊ทธ๋žจ์€ ์‹ค์ œ๋กœ ์•„๋ฌด ์ผ๋„ ํ•˜์ง€ ๋ชปํ•œ ์ฑ„ I/O ์ž‘์—…์ด ๋๋‚˜๊ธฐ๋งŒ์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒํ™ฉ์ด ๋‹ฌ๋ผ์ง„๋‹ค.

ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ I/O ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ๋Œ€๊ธฐํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ CPU๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค์Œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด CPU๊ฐ€ ๋†€์ง€ ์•Š๊ณ  ๊ณ„์† ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋œ๋‹ค.

๊ทธ๋ž˜์„œ I/O ์ž‘์—…์ด ๋งŽ์€ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” CPU ์ฝ”์–ด ์ˆ˜๋ณด๋‹ค ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์— ๋„์›€์ด ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ„์† ๋Š˜๋ฆฌ๋ฉด Context Switching ์ฆ๊ฐ€, ๋™๊ธฐํ™” ๋น„์šฉ ์ฆ๊ฐ€, ๋ถˆํ•„์š”ํ•œ ์ž์›์‚ฌ์šฉ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”๋ฐ??๋ผ๋Š” ์˜๋ฌธ์ด ๋“ค์ˆ˜์žˆ๋‹ค. ์ •๋‹ต์ด๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด๋Š” ๋”ฐ๋กœ ๋น„๋™๊ธฐ I/O ๊ธฐ๋ฐ˜์˜ ์ด๋ฒคํŠธ ๋ชจ๋ธ์ด ์กด์žฌํ•œ๋‹ค. ์ด์— ๋Œ€ํ•ด์„œ๋Š” ์ถ”ํ›„ ๋‹ค๋ฅธ ๊ธ€์—์„œ ์„ค๋ช…์„ ํ•˜๊ฒ ๋‹ค.


์ •๋ฆฌ


์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋“  ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•˜์—ฌ ๊ฐœ๋ฐœ์ด ๋” ์‰ฝ๊ณ  CPU, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ๊ฒŒ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด Race Condition, Deadlock, Synchronization๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๊ณ ๋ คํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ๊ฐ€ ํ›จ์”ฌ ๋ณต์žกํ•ด์ง€๊ณ  ๊ฐœ๋ฐœ ๋‚œ์ด๋„๋„ ํฌ๊ฒŒ ์˜ฌ๋ผ๊ฐ„๋‹ค.

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” ๋ถ„๋ช… ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ์ˆ ์ด์ง€๋งŒ, ๋ฌดํ„ฑ๋Œ€๊ณ  ์ ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ•ญ์ƒ ์ข‹์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ์ž˜๋ชป ์„ค๊ณ„ํ•˜๋ฉด ์„ฑ๋Šฅ๊ณผ ์•ˆ์ •์„ฑ ๋ชจ๋‘๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฌ๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ค‘์š”ํ•œ ๊ฒƒ์€ โ€œ์Šค๋ ˆ๋“œ๋ฅผ ๋งŽ์ด ๋งŒ๋“œ๋Š” ๊ฒƒโ€์ด ์•„๋‹ˆ๋ผ โ€œ์ ์ ˆํ•œ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒโ€์ด๋‹ค.

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ: