Post

[OS] Process์™€ Thread

[OS] Process์™€ Thread

๐Ÿงฉ Process

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

๋ฉ”๋ชจ๋ฆฌ ๊ฒฉ๋ฆฌ์™€ ์ฃผ์†Œ ๊ณต๊ฐ„

ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ ์‹œ ์šด์˜์ฒด์ œ๋Š” ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค ์ „์šฉ์˜ ๊ฐ€์ƒ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณต๊ฐ„์€ ์‹คํ–‰ ์ฝ”๋“œ๊ฐ€ ๋‹ด๊ธด Text, ์ „์—ญ ๋ฐ ์ •์  ๋ณ€์ˆ˜๊ฐ€ ์œ„์น˜ํ•œ Data, ๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ์œ„ํ•œ Heap, ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Stack์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.

์ด ์„ค๊ณ„์˜ ๋ชฉ์ ์€ ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ๋…๋ฆฝ์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ์ฃผ์†Œ ๊ณต๊ฐ„์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ํ—ˆ์šฉ๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์นจ๋ฒ”ํ•  ๊ฒฝ์šฐ ํ•˜๋“œ์›จ์–ด(MMU)์™€ ์šด์˜์ฒด์ œ๊ฐ€ ์ด๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋ฐœ์ƒํ•˜๋Š” Segmentation Fault๋Š” ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฆ‰์‹œ ์ข…๋ฃŒ์‹œ์ผœ ์‹œ์Šคํ…œ ์ „์ฒด์˜ ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

PCB์˜ ์ •๋ณด์™€ ์—ญํ• 

์šด์˜์ฒด์ œ๋Š” ์ˆ˜๋งŽ์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ํ”„๋กœ์„ธ์Šค์˜ ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•œ PCB(Process Control Block)๋ฅผ ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. PCB๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ค‘๋‹จ๋˜์—ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋  ๋•Œ ์ด์ „์˜ ์‹คํ–‰ ์ƒํƒœ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณต์›ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.

PCB์—๋Š” ํ”„๋กœ์„ธ์Šค ์‹๋ณ„์„ ์œ„ํ•œ PID, ํ˜„์žฌ ์‹คํ–‰ ์ƒํƒœ(New, Ready, Running, Waiting, Terminated), ๋‹ค์Œ์— ์‹คํ–‰ํ•  ๋ช…๋ น์–ด ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” Program Counter, ๊ทธ๋ฆฌ๊ณ  CPU ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’๊ณผ ๋ฉ”๋ชจ๋ฆฌ ๋งคํ•‘ ์ •๋ณด ๋“ฑ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์„ธ์Šค์˜ ์ƒ๋ช… ์ฃผ๊ธฐ์™€ fork()

์œ ๋‹‰์Šค ๊ณ„์—ด ์‹œ์Šคํ…œ์—์„œ๋Š” fork() ์‹œ์Šคํ…œ ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณต์ œํ•ด ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” ๋ถ€๋ชจ์˜ PCB ์ •๋ณด์™€ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋ฅผ ์ƒ์†๋ฐ›์•„ ๋…๋ฆฝ์ ์ธ ์‹คํ–‰ ํ๋ฆ„์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

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
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    pid_t pid;

    printf("fork() ํ˜ธ์ถœ ์ „. (๋ถ€๋ชจ PID: %d)\n", getpid());

    // ์ƒˆ๋กœ์šด ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ (๋ถ€๋ชจ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ๋ณต์ œ)
    pid = fork();

    if (pid < 0) {
        // fork ์‹คํŒจ
        fprintf(stderr, "fork failed\n");
        return 1;
    } else if (pid == 0) {
        // ์ž์‹ ํ”„๋กœ์„ธ์Šค ์ฝ”๋“œ ์˜์—ญ
        // ์ž์‹์—๊ฒŒ fork์˜ ๋ฐ˜ํ™˜๊ฐ’์€ 0์ž…๋‹ˆ๋‹ค.
        printf("์ €๋Š” ์ž์‹ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค. (PID: %d, ๋ถ€๋ชจ PID: %d)\n", getpid(), getppid());
    } else {
        // ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค ์ฝ”๋“œ ์˜์—ญ
        // ๋ถ€๋ชจ์—๊ฒŒ fork์˜ ๋ฐ˜ํ™˜๊ฐ’์€ ์ƒ์„ฑ๋œ ์ž์‹์˜ PID์ž…๋‹ˆ๋‹ค.
        printf("์ €๋Š” ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค. (PID: %d, ์ž์‹ PID: %d)\n", getpid(), pid);
    }

    // ๋ถ€๋ชจ์™€ ์ž์‹ ๋ชจ๋‘ ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€๋งŒ, ๊ฐ์ž์˜ ์ฃผ์†Œ ๊ณต๊ฐ„์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
    printf("ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ. (PID: %d)\n", getpid());

    return 0;
}

ํ”„๋กœ์„ธ์Šค ๊ต์ฒด ๊ณผ์ •

CPU ์ฝ”์–ด๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๋งŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์šด์˜์ฒด์ œ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๋งค์šฐ ์งง์€ ์‹œ๊ฐ„ ๋‹จ์œ„๋กœ ๊ต์ฒดํ•˜๋Š” ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์„ ํ†ตํ•ด ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ œ์–ด๊ถŒ์ด ์ปค๋„ ๋ชจ๋“œ๋กœ ์ „ํ™˜๋ฉ๋‹ˆ๋‹ค.
  2. ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์˜ ๋ ˆ์ง€์Šคํ„ฐ ์ƒํƒœ๋ฅผ ํ•ด๋‹น PCB์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  3. ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ๋‹ค์Œ์— ์‹คํ–‰ํ•  ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  4. ์ƒˆ๋กœ ์„ ํƒ๋œ ํ”„๋กœ์„ธ์Šค์˜ PCB์—์„œ ๋ ˆ์ง€์Šคํ„ฐ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค.
  5. ์œ ์ € ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค ์‹คํ–‰์„ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์€ ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์„ ์œ„ํ•œ ํ•„์ˆ˜์ ์ธ ์ ˆ์ฐจ์ด์ง€๋งŒ, CPU๊ฐ€ ์‹ค์ œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋Š” ์ˆœ์ˆ˜ ์˜ค๋ฒ„ํ—ค๋“œ ๋น„์šฉ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿงฉ Thread

์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ํ๋ฆ„์˜ ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ํ”„๋กœ์„ธ์Šค์— ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ์ค‘ ํž™ ์˜์—ญ๊ณผ ๋ฐ์ดํ„ฐ ์˜์—ญ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž์› ๊ณต์œ  ๋•๋ถ„์— ์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค๋ณด๋‹ค ์ƒ์„ฑ ๋น„์šฉ์ด ์ €๋ ดํ•˜๋ฉฐ, ๋ณ„๋„์˜ ํ†ต์‹  ๊ณผ์ • ์—†์ด ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ์ฝ๊ณ  ์“ฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์› ๊ณต์œ ์™€ ์‹คํ–‰ ํ๋ฆ„

์Šค๋ ˆ๋“œ์˜ ๋ณธ์งˆ์€ ์‹คํ–‰ ํ๋ฆ„์˜ ๋ถ„๋ฆฌ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋Š” ์†Œ์†๋œ ํ”„๋กœ์„ธ์Šค์˜ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๊ณต์œ ํ•˜๋˜, ๊ฐ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ์œ„์น˜์™€ ์—ฐ์‚ฐ ์ค‘์ธ ์ž„์‹œ ๊ฐ’์€ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ณต์œ ๋˜๋Š” ์ž์›๊ณผ ๊ฒฉ๋ฆฌ๋˜๋Š” ์˜์—ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.

  • ๊ณต์œ  ์˜์—ญ: ์ฝ”๋“œ(Text), ์ „์—ญ ๋ณ€์ˆ˜(Data), ๋™์  ํ• ๋‹น ๋ฉ”๋ชจ๋ฆฌ(Heap), ์—ด๋ฆฐ ํŒŒ์ผ ํ•ธ๋“ค ๋“ฑ ํ”„๋กœ์„ธ์Šค์˜ ๊ณต์šฉ ์ž์›.
  • ๊ฒฉ๋ฆฌ ์˜์—ญ: ๊ฐ ์Šค๋ ˆ๋“œ๋งŒ์˜ ๋…๋ฆฝ์ ์ธ ์Šคํƒ๊ณผ ๋ ˆ์ง€์Šคํ„ฐ ์ง‘ํ•ฉ(PC ๋“ฑ).

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ ๋•๋ถ„์— ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์€ ํ”„๋กœ์„ธ์Šค ์ „ํ™˜๋ณด๋‹ค ๋น„์šฉ์ด ์ ๊ฒŒ ๋“ญ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์„ ๊ต์ฒดํ•  ํ•„์š” ์—†์ด CPU ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

TCB์™€ ์ „์šฉ ์Šคํƒ ํ• ๋‹น

์šด์˜์ฒด์ œ ์Šค์ผ€์ค„๋ง์˜ ์ตœ์†Œ ๋‹จ์œ„๋Š” ์Šค๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค. ์ปค๋„์€ ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด TCB(Thread Control Block)๋ผ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์—๋Š” ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰ ์ƒํƒœ, CPU ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’, ์Šคํƒ ํฌ์ธํ„ฐ ๋“ฑ์ด ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

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

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
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜ (Data ์˜์—ญ)
int shared_counter = 0;

// ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ํ•  ํ•จ์ˆ˜
void *thread_function(void *arg) {
    char *thread_name = (char *)arg;
    int i;
    // ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ์ž์‹ ๋งŒ์˜ ์Šคํƒ์— ์ง€์—ญ ๋ณ€์ˆ˜ i๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
    for (i = 0; i < 1000000; i++) {
        // ๊ณต์œ  ๋ณ€์ˆ˜์— ๋™์‹œ ์ ‘๊ทผ (๊ฒฝ์Ÿ ์ƒํƒœ ๋ฐœ์ƒ ๊ฐ€๋Šฅ)
        shared_counter++;
    }
    printf("%s ์ž‘์—… ์™„๋ฃŒ.\n", thread_name);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    // ๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
    // ๊ฐ ์Šค๋ ˆ๋“œ๋Š” thread_function์„ ์‹คํ–‰ํ•˜๋ฉฐ, ๋™์ผํ•œ shared_counter๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
    pthread_create(&thread1, NULL, thread_function, "Thread 1");
    pthread_create(&thread2, NULL, thread_function, "Thread 2");

    // ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ (๋ฉ”์ธ ์Šค๋ ˆ๋“œ ๋ธ”๋กœํ‚น)
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // ๊ฒฐ๊ณผ ์ถœ๋ ฅ (๋™๊ธฐํ™”๊ฐ€ ์—†๋‹ค๋ฉด 2000000์ด ์•„๋‹ ์ˆ˜ ์žˆ์Œ)
    printf("์ตœ์ข… ์นด์šดํ„ฐ ๊ฐ’: %d\n", shared_counter);

    return 0;
}

๋ฐ์ดํ„ฐ ์ถฉ๋Œ๊ณผ ๋™๊ธฐํ™”

์ž์›์„ ๊ณต์œ ํ•œ๋‹ค๋Š” ํŠน์ง•์€ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ž์›์— ๋™์‹œ์— ์ ‘๊ทผํ•˜์—ฌ ๊ฐ’์„ ์ˆ˜์ •ํ•  ๋•Œ ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

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

์ž ๊ธˆ ์žฅ์น˜์™€ ๋ณ‘๋ ฌ์„ฑ ์ €ํ•˜

์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ(Thread Safety)์„ ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•ด ๋ฎคํ…์Šค๋‚˜ ์„ธ๋งˆํฌ์–ด ๊ฐ™์€ ์ž ๊ธˆ ์žฅ์น˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ‘๋ ฌ์„ฑ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์ž์›์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๋“ค์ด ๋Œ€๊ธฐ ์ƒํƒœ์— ๋จธ๋ฌผ๊ฒŒ ๋˜๋ฉด์„œ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๊ธ‰๊ฐํ•˜๋Š” ์ž ๊ธˆ ๊ฒฝํ•ฉ(Lock Contention) ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ ํšจ์œจ์ ์ธ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ํ•ต์‹ฌ์€ ๋‹จ์ˆœํžˆ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๊ณต์œ  ์ž์›์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋™๊ธฐํ™” ๋น„์šฉ์„ ์ค„์ด๋Š” ์„ค๊ณ„์— ์žˆ์Šต๋‹ˆ๋‹ค.

Cache Pollution

์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์˜ ๋น„์šฉ์€ ๋ ˆ์ง€์Šคํ„ฐ ์ €์žฅ๊ณผ ๋ณต์›๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์บ์‹œ ์˜ค์—ผ์—์„œ๋„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ต์ฒด๋œ ์งํ›„ ํ•˜๋“œ์›จ์–ด ์บ์‹œ์˜ ํšจ์œจ์ด ๊ธ‰๊ฒฉํžˆ ๋–จ์–ด์ง€๋Š” ํ˜„์ƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ ๋ฐ์ดํ„ฐ ๋ฌดํšจํ™”

CPU๋Š” ๋žจ์˜ ์†๋„ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด L1, L2, L3 ์บ์‹œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ์ค‘์—๋Š” ์ฐธ์กฐ ๊ตญ์†Œ์„ฑ ์›๋ฆฌ์— ๋”ฐ๋ผ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ์™€ ๋ช…๋ น์–ด๊ฐ€ ์บ์‹œ์— ์ ์žฌ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ์ผ์–ด๋‚˜๋ฉด ์ƒˆ๋กœ์šด ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ธฐ์กด ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ€์–ด๋‚ด๊ณ  ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ„์šฐ๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๊ธฐ์กด ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ตฌ์ถ•ํ•ด๋‘” ์›Œํ‚น ์…‹์ด ์œ ์‹ค๋ฉ๋‹ˆ๋‹ค. ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฒ•์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ ๋น„์šฉ์€ ์ค„์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฌผ๋ฆฌ์ ์ธ ์บ์‹œ ์ ์œ  ์ƒํƒœ๊นŒ์ง€ ๋ณด์กดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๊ต์ฒด ์งํ›„์˜ ์†๋„ ํ•˜๋ฝ

์บ์‹œ ์˜ค์—ผ์€ ํ”„๋กœ์„ธ์Šค ์žฌ์‹คํ–‰ ์‹œ ์บ์‹œ ๋ฏธ์Šค์˜ ์ฆ๊ฐ€๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. CPU๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆฐ ๋žจ์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์—ฐ์‚ฐ ์†๋„๊ฐ€ ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค.

ํŠนํžˆ ๊ณ ๋ถ€ํ•˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”์ธ์ด ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค.

  • TLB Flush: ์ฃผ์†Œ ๋ณ€ํ™˜ ์ •๋ณด๋ฅผ ๋‹ด์€ TLB๊ฐ€ ์Šค์œ„์นญ ์‹œ์ ์— ๋ฌดํšจํ™”๋˜๊ฑฐ๋‚˜ ๊ต์ฒด๋˜์–ด ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ํšจ์œจ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.
  • ์ƒํƒœ ๋ณต๊ตฌ ๋น„์šฉ: ์บ์‹œ ํžˆํŠธ์œจ์ด ์ •์ƒ ๊ถค๋„์— ์˜ค๋ฅด๊ธฐ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์ฝœ๋“œ ์บ์‹œ ๊ตฌ๊ฐ„์—์„œ ์‹œ์Šคํ…œ ๋ ˆ์ดํ„ด์‹œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ณผ๋„ํ•œ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ์ด ์œ„ํ—˜ํ•œ ์ด์œ 

CPU ์ฝ”์–ด ์ˆ˜๋ณด๋‹ค ์Šค๋ ˆ๋“œ๋ฅผ ๊ณผํ•˜๊ฒŒ ์ƒ์„ฑํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋นˆ๋„๊ฐ€ ๋†’์•„์ ธ ์บ์‹œ ์˜ค์—ผ์ด ์ƒ์‹œํ™”๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‹ค์ œ ์—ฐ์‚ฐ๋ณด๋‹ค ์บ์‹œ๋ฅผ ๊ต์ฒดํ•˜๋Š” ์ž‘์—…์— ์ž์›์ด ๋‚ญ๋น„๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค.

Copy-on-Write

fork() ์‹œ์Šคํ…œ ์ฝœ ํ˜ธ์ถœ ์‹œ ์šด์˜์ฒด์ œ๊ฐ€ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ์ „์ฒด๋ฅผ ์ฆ‰์‹œ ๋ณต์‚ฌํ•˜๋ฉด ์ƒ๋‹นํ•œ ์ž์›๊ณผ ์‹œ๊ฐ„์ด ์†Œ๋ชจ๋ฉ๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ๋Š” ์ด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ๊ธฐ ์‹œ ๋ณต์‚ฌ(์ดํ•˜ COW)๋ผ๋Š” ์ง€์—ฐ ๋ณต์‚ฌ ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

fork์™€ ์ง€์—ฐ ๋ณต์‚ฌ ์ „๋žต

COW๋Š” ์‹ค์ œ ์ˆ˜์ •์ด ๋ฐœ์ƒํ•˜๊ธฐ ์ „๊นŒ์ง€ ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๋ฅผ ๋ฏธ๋ฃจ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. fork()๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์šด์˜์ฒด์ œ๋Š” ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ  ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์˜ ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”๋งŒ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค.

์ด ์‹œ์ ์— ๋ถ€๋ชจ์™€ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” ๋™์ผํ•œ ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ํŽ˜์ด์ง€๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹ ๋•๋ถ„์— ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ์™€ ๊ด€๊ณ„์—†์ด ์ƒ์„ฑ ์ž‘์—…์ด ๋น ๋ฅด๊ฒŒ ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ˆ˜์ •๊ณผ ์‹ค์ œ ๋ณต์‚ฌ

ํ”„๋กœ์„ธ์Šค ๊ฐ„ ๊ฒฉ๋ฆฌ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์šด์˜์ฒด์ œ๋Š” ๊ณต์œ  ์ค‘์ธ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํŠน์ • ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๋•Œ ์‹ค์ œ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

  1. ํŽ˜์ด์ง€ ํดํŠธ ๋ฐœ์ƒ: ์ฝ๊ธฐ ์ „์šฉ ํŽ˜์ด์ง€์— ์“ฐ๊ธฐ๋ฅผ ์‹œ๋„ํ•˜๋ฉด ํ•˜๋“œ์›จ์–ด๊ฐ€ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
  2. ์ปค๋„ ๊ฐœ์ž…: ์šด์˜์ฒด์ œ๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€์˜ COW ์„ค์ •์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  3. ์ง€์—ฐ๋œ ๋ณต์‚ฌ: ์“ฐ๊ธฐ๋ฅผ ์‹œ๋„ํ•œ ์‹œ์ ์— ํ•ด๋‹น ํŽ˜์ด์ง€๋งŒ ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ƒˆ๋กœ์šด ์˜์—ญ์œผ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  4. ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ” ์—…๋ฐ์ดํŠธ: ๋ณต์‚ฌ๋œ ์ƒˆ๋กœ์šด ๋ฌผ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ…Œ์ด๋ธ”์„ ์ˆ˜์ •ํ•˜๊ณ  ๊ถŒํ•œ์„ ์ฝ๊ธฐ/์“ฐ๊ธฐ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

Redis์˜ ์ค‘๋‹จ ์—†๋Š” ์Šค๋ƒ…์ƒท

Redis๋Š” BGSAVE ๋ช…๋ น ์‹œ fork()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. COW๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์„œ๋น„์Šค ์ค‘๋‹จ ์—†์ด ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ƒ์„ฑ ์‹œ์ ์˜ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋ฅผ ์Šค๋ƒ…์ƒท์œผ๋กœ ์œ ์ง€ํ•˜๋ฉฐ ๋””์Šคํฌ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    // ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ๋ณ€์ˆ˜
    int data = 100;
    pid_t pid;

    printf("fork() ์ „: data = %d, ์ฃผ์†Œ = %p\n", data, &data);

    pid = fork();

    if (pid < 0) {
        fprintf(stderr, "fork error\n");
        return 1;
    } else if (pid == 0) {
        // [์ž์‹ ํ”„๋กœ์„ธ์Šค]
        // ์ด ์‹œ์ ๊นŒ์ง€๋Š” COW์— ์˜ํ•ด ๋ถ€๋ชจ์™€ ๋™์ผํ•œ ๋ฌผ๋ฆฌ ํŽ˜์ด์ง€๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
        printf("[์ž์‹] ์“ฐ๊ธฐ ์ „: data = %d, ์ฃผ์†Œ = %p (๋ถ€๋ชจ์™€ ๊ฐ€์ƒ ์ฃผ์†Œ ๋™์ผ)\n", data, &data);
        
        // ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ์ˆœ๊ฐ„, ํŽ˜์ด์ง€ ๋ณต์‚ฌ(COW)๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
        data = 200;
        printf("[์ž์‹] ์“ฐ๊ธฐ ํ›„: data = %d, ์ฃผ์†Œ = %p (๊ฐ’ ๋ณ€๊ฒฝ๋จ, ์ƒˆ๋กœ์šด ๋ฌผ๋ฆฌ ํŽ˜์ด์ง€)\n", data, &data);
    } else {
        // [๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค]
        // ์ž์‹์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜์—ฌ ์ถœ๋ ฅ์ด ์„ž์ด์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
        wait(NULL); 
        // ๋ถ€๋ชจ์˜ ๋ฐ์ดํ„ฐ๋Š” ์ž์‹์˜ ์ˆ˜์ •์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค (๊ฒฉ๋ฆฌ ๋ณด์žฅ).
        printf("[๋ถ€๋ชจ] ์ž์‹ ์ข…๋ฃŒ ํ›„: data = %d, ์ฃผ์†Œ = %p (๊ฐ’ ์œ ์ง€๋จ)\n", data, &data);
    }

    return 0;
}

M:N Scheduling

์šด์˜์ฒด์ œ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ปค๋„ ์Šค๋ ˆ๋“œ๋Š” ์ƒ์„ฑ ์‹œ ์•ฝ 1MB์˜ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋˜๋ฉฐ, ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ๋งˆ๋‹ค ์ปค๋„ ๋ชจ๋“œ ์ง„์ž…์ด ํ•„์š”ํ•˜์—ฌ ๋น„์šฉ์ด ๋†’์Šต๋‹ˆ๋‹ค. ๋Œ€๊ทœ๋ชจ ๋™์‹œ ์ ‘์†์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์‹œ์Šคํ…œ์—์„œ ์ ‘์†์ž๋งˆ๋‹ค ์ปค๋„ ์Šค๋ ˆ๋“œ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์€ ์ž์› ๋ถ€์กฑ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์œ ์ € ๋ ˆ๋ฒจ ์Šค๋ ˆ๋“œ์™€ ์ปค๋„ ์Šค๋ ˆ๋“œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” M:N ์Šค์ผ€์ค„๋ง์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๋งคํ•‘ ๋ฐฉ์‹

์Šค๋ ˆ๋“œ ๋ชจ๋ธ์€ ๊ธฐ์ˆ ์  ์š”๊ตฌ์— ๋”ฐ๋ผ ์„ธ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.

  1. 1:1 ๋ชจ๋ธ: ์œ ์ € ์Šค๋ ˆ๋“œ ํ•˜๋‚˜๊ฐ€ ์ปค๋„ ์Šค๋ ˆ๋“œ ํ•˜๋‚˜์— ์ง์ ‘ ๋งคํ•‘๋˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์˜ ์ „ํ†ต์ ์ธ ๋ฒ„์ „์ด๋‚˜ C++์—์„œ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™œ์šฉ์— ์œ ๋ฆฌํ•˜์ง€๋งŒ ์ƒ์„ฑ๊ณผ ์Šค์œ„์นญ ๋น„์šฉ์ด ํฝ๋‹ˆ๋‹ค.
  2. N:1 ๋ชจ๋ธ: ์—ฌ๋Ÿฌ ์œ ์ € ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์ปค๋„ ์Šค๋ ˆ๋“œ ์œ„์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์€ ๋น ๋ฅด์ง€๋งŒ, ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—์„œ ๋ธ”๋กœํ‚น ์‹œ์Šคํ…œ ์ฝœ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์ปค๋„ ์Šค๋ ˆ๋“œ์— ์†ํ•œ ๋ชจ๋“  ์œ ์ € ์Šค๋ ˆ๋“œ๊ฐ€ ์ค‘๋‹จ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. M:N ๋ชจ๋ธ: ๋‹ค์ˆ˜์˜ ์œ ์ € ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ์ˆ˜์˜ ์ปค๋„ ์Šค๋ ˆ๋“œ์— ๋™์ ์œผ๋กœ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. Go ์–ธ์–ด์˜ ๊ณ ๋ฃจํ‹ด์ด๋‚˜ ์ž๋ฐ” 21์˜ ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

M:N ๋ชจ๋ธ์—์„œ๋Š” ์šด์˜์ฒด์ œ๊ฐ€ ์•„๋‹Œ ์–ธ์–ด์˜ ๋Ÿฐํƒ€์ž„ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์œ ์ € ์Šค๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์–ด๋–ค ์ปค๋„ ์Šค๋ ˆ๋“œ์— ์ž‘์—…์„ ์˜ฌ๋ฆด์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

๋Ÿฐํƒ€์ž„ ์ž‘์—… ๋ถ„๋ฐฐ

M:N ๋ชจ๋ธ์˜ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ ํ•˜๋‚˜๋Š” ์›Œํฌ ์Šคํ‹ธ๋ง(Work Stealing)์ž…๋‹ˆ๋‹ค. ํŠน์ • ์ปค๋„ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋œ ์ž‘์—…์„ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ž‘์—… ํ์—์„œ ํƒœ์Šคํฌ๋ฅผ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ CPU ๊ฐ€๋™๋ฅ ์„ ๊ทน๋Œ€ํ™”ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ๋„ ๋†’์Šต๋‹ˆ๋‹ค. ๊ณ ๋ฃจํ‹ด์€ ์ˆ˜ KB์˜ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์‹œ์ž‘ํ•˜์—ฌ ํ•„์š”์— ๋”ฐ๋ผ ์Šคํƒ ํฌ๊ธฐ๋ฅผ ๋™์ ์œผ๋กœ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ” 21์˜ ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ ๋˜ํ•œ ๋ธ”๋กœํ‚น I/O ๋ฐœ์ƒ ์‹œ ์ปค๋„ ์Šค๋ ˆ๋“œ๋ฅผ ์ ์œ ํ•˜์ง€ ์•Š๊ณ  ์–‘๋ณด(Yield)ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ์ˆ˜๋งŽ์€ ์‹คํ–‰ ํ๋ฆ„์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

M:N ๋ชจ๋ธ์˜ ๋ชจ๋‹ˆํ„ฐ๋ง ๋น„์šฉ

M:N ๋ชจ๋ธ์€ ์„ฑ๋Šฅ ํšจ์œจ์ด ๋†’์ง€๋งŒ, ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์ถ”์ ์ด ๋ณต์žกํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ์ € ์Šค๋ ˆ๋“œ์—์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๊ฐ€ ์–ด๋А ์ปค๋„ ์Šค๋ ˆ๋“œ ๋ฌธ๋งฅ์—์„œ ์‹คํ–‰๋˜์—ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

public class VirtualThreadDemo {
    public static void main(String[] args) {
        // 10๋งŒ ๊ฐœ์˜ ๋™์‹œ ์ž‘์—… ์ˆ˜ํ–‰. ๊ธฐ์กด ํ”Œ๋žซํผ ์Šค๋ ˆ๋“œ(1:1 ๋ชจ๋ธ)๋กœ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ(OOM)์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ทœ๋ชจ์ž…๋‹ˆ๋‹ค.
        int numTasks = 100_000;

        System.out.printf("%d๊ฐœ์˜ ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ ์ž‘์—… ์ƒ์„ฑ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค...\n", numTasks);
        Instant start = Instant.now();

        // Executors.newVirtualThreadPerTaskExecutor()๋Š” ๊ฐ ์ž‘์—…๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
        // try-with-resources ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธ”๋ก์„ ๋น ์ ธ๋‚˜๊ฐˆ ๋•Œ executor.close()๊ฐ€ ํ˜ธ์ถœ๋˜์–ด
        // ์ œ์ถœ๋œ ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค (Structured Concurrency).
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            IntStream.range(0, numTasks).forEach(i -> {
                executor.submit(() -> {
                    try {
                        // ๊ฐ ์Šค๋ ˆ๋“œ๋Š” I/O ์ž‘์—…์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด ์ž ์‹œ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.
                        // ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ๋Š” ๋ธ”๋กœํ‚น ์‹œ ์บ๋ฆฌ์–ด ์Šค๋ ˆ๋“œ(์ปค๋„ ์Šค๋ ˆ๋“œ)๋ฅผ ์ ์œ ํ•˜์ง€ ์•Š๊ณ  '์–‘๋ณด(Yield)'ํ•ฉ๋‹ˆ๋‹ค.
                        Thread.sleep(Duration.ofMillis(100));
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            });
        } // ์—ฌ๊ธฐ์„œ ๋ชจ๋“  ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ์˜ ์ž‘์—…์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

        Instant end = Instant.now();
        System.out.printf("๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์†Œ์š” ์‹œ๊ฐ„: %d ms\n", Duration.between(start, end).toMillis());
        // ๊ฒฐ๊ณผ์ ์œผ๋กœ ์†Œ์ˆ˜์˜ ์ปค๋„ ์Šค๋ ˆ๋“œ๋งŒ์œผ๋กœ 10๋งŒ ๊ฐœ์˜ ๋…ผ๋ฆฌ์  ์‹คํ–‰ ํ๋ฆ„์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด๋ƒ…๋‹ˆ๋‹ค.
    }
}

Summary

ํ˜„๋Œ€ ์ปดํ“จํŒ… ๊ตฌ์กฐ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ๊ฒฉ๋ฆฌ์™€ ์Šค๋ ˆ๋“œ์˜ ์ž์› ๊ณต์œ  ์‚ฌ์ด์˜ ๊ท ํ˜•์„ ๋งž์ถ”๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ๋Š” ๊ฐ€์ƒ ์ฃผ์†Œ ๊ณต๊ฐ„๊ณผ PCB๋ฅผ ํ†ตํ•ด ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ์„ ํ™•๋ณดํ•˜๋ฉฐ, ์“ฐ๊ธฐ ์‹œ ๋ณต์‚ฌ์™€ M:N ์Šค์ผ€์ค„๋ง์„ ํ†ตํ•ด ํ•˜๋“œ์›จ์–ด ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์œผ๋กœ ์ธํ•œ ์บ์‹œ ์˜ค์—ผ๊ณผ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์˜ ์ž ๊ธˆ ๊ฒฝํ•ฉ ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๊ณผ์ œ๋กœ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์„œ๋น„์Šค์˜ ๋ถ€ํ•˜ ํŠน์„ฑ์— ๋งž๋Š” ์ ์ ˆํ•œ ์‹คํ–‰ ๋ชจ๋ธ์„ ์„ ํƒํ•˜๋Š” ์„ค๊ณ„ ๋Šฅ๋ ฅ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

References

This post is licensed under CC BY 4.0 by the author.