๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ์šด์˜์ฒด์ œ

[pthread] Thread ์‹ค์Šต (์šด์˜์ฒด์ œ๐Ÿฆ– ๊ฐ•์˜-Chpater4. Thread & Cocurrency)

by ๋ถˆํƒ€๋Š” ์ฐธ์ƒˆ 2025. 2. 28.

1. Thread์˜ ๊ฐœ๋…

Thread์˜ ์ข…๋ฅ˜

Thread๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

  1. User Thread: ์ปค๋„์˜ ์ง์ ‘์ ์ธ ์ง€์› ์—†์ด ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์—์„œ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  2. Kernel Thread: ์ปค๋„์ด ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋Š” ์“ฐ๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค.

User Thread์™€ Kernel Thread ๊ฐ„์˜ ๊ด€๊ณ„ ๋ชจ๋ธ

  • Many-to-One Model: ์—ฌ๋Ÿฌ ๊ฐœ์˜ user thread๊ฐ€ ํ•˜๋‚˜์˜ kernel thread์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.
  • One-to-One Model: ๊ฐ๊ฐ์˜ user thread๊ฐ€ ํ•˜๋‚˜์˜ kernel thread์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.
  • Many-to-Many Model: ์—ฌ๋Ÿฌ ๊ฐœ์˜ user thread๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ kernel thread์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.

 

2. Thread ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

Thread ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ๋Œ€ํ‘œ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • POSIX Pthreads (Linux, Unix ํ™˜๊ฒฝ)
  • Windows Thread (Windows ํ™˜๊ฒฝ)
  • Java Thread (JVM ๊ธฐ๋ฐ˜)

์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” POSIX Pthreads๋ฅผ ์ด์šฉํ•˜์—ฌ thread๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹ค์Šตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

3. Pthreads ์‹ค์Šต

3.1 Pthreads ์‹ค์Šต 1: ๊ฐ„๋‹จํ•œ Thread ์ƒ์„ฑ ๋ฐ ์‹คํ–‰

#include <stdio.h>
#include <stdlib.h> // atoi() ํ•จ์ˆ˜ ์‚ฌ์šฉ (๋ฌธ์ž์—ด์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜)
#include <pthread.h> //POSIX Thread ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

int sum; //์ „์—ญ ๋ณ€์ˆ˜ ์„ ์–ธ

void *runner(void *param); //์“ฐ๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋  ํ•จ์ˆ˜ ์„ ์–ธ

int main(int argc, char *argv[]) //argc: ๋ช…๋ น์ค„ ์ธ์ž ๊ฐœ์ˆ˜, argv: ๋ช…๋ น์ค„ ์ธ์ž ๋ฐฐ์—ด
{
    pthread_t tid; //์“ฐ๋ ˆ๋“œ ์•„์ด๋””๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜
    pthread_attr_t attr; //์“ฐ๋ ˆ๋“œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜

    pthread_attr_init(&attr); //์“ฐ๋ ˆ๋“œ ์†์„ฑ ์ดˆ๊ธฐํ™”
    pthread_create(&tid, &attr, runner, argv[1]); // runner ํ•จ์ˆ˜ ์‹คํ–‰, argv[1] ์ „๋‹ฌ
    pthread_join(tid, NULL); // Thread๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ (๋ฉ”์ธ ํ•จ์ˆ˜๊ฐ€ ๋จผ์ € ๋๋‚˜์ง€ ์•Š๊ฒŒ)

    printf("sum = %d\n", sum);
}

void *runner(void *param)
{
    int i, upper = atoi(param); //atoi๋กœ ๋ฌธ์ž์—ด์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜
    sum = 0;
    for (i = 1; i <= upper; i++)
        sum += i;
    pthread_exit(0); //์‹คํ–‰์ด ๋๋‚ฌ์Œ์„ ์•Œ๋ฆฌ๊ณ  ์ข…๋ฃŒ
}

์‹คํ–‰ ์˜ˆ์‹œ

gcc -pthread pthread_example1.c -o pthread_example1
./pthread_example1 10
-> sum = 55

์ฝ”๋“œ ์„ค๋ช…

  • pthread_create()๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  runner ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • pthread_join()์„ ํ˜ธ์ถœํ•˜์—ฌ ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
  • runner ํ•จ์ˆ˜๋Š” ์ „๋‹ฌ๋œ upper ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ 1๋ถ€ํ„ฐ ํ•ด๋‹น ๊ฐ’๊นŒ์ง€์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
๋”๋ณด๊ธฐ

ํฌ์ธํ„ฐ ๊ฐœ๋…์„ ๋งŽ์ด ๊นŒ๋จน์–ด์„œ ์˜ˆ์ œ์—์„œ ํฌ์ธํ„ฐ ์“ฐ์—ฌ์ง„ ๋ถ€๋ถ„ ์ •๋ฆฌ

1๏ธโƒฃ void *runner(void *param);

๐Ÿ“Œ void *runner

  • void * → ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ผ๋Š” ๋œป
  • ์ฆ‰, runner() ํ•จ์ˆ˜๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋“  ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋Š” ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธ.
  • ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” pthread_exit(0);์œผ๋กœ ๋๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜ํ™˜๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง„ ์•Š์Œ.

๐Ÿ“Œ void *param

  • param ์•ž์˜ *๋Š” ํฌ์ธํ„ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ผ๋Š” ๋œป.
  • ์ฆ‰, param์€ ์–ด๋–ค ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋“  ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋Š” ํฌ์ธํ„ฐ.
  • pthread_create()๋กœ ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ, ์‹คํ–‰ํ•  ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํฌ์ธํ„ฐ ํ•˜๋‚˜๋งŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ.
  • ๊ทธ๋ž˜์„œ param์„ void * ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•ด์„œ ์–ด๋–ค ํƒ€์ž…์ด๋“  ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•จ.

๐Ÿ’ก ์™œ ํฌ์ธํ„ฐ(void *param)๋ฅผ ์“ฐ๋Š” ๊ฑธ๊นŒ?
์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ, ์‹คํ–‰ํ•  ํ•จ์ˆ˜์— ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ ๋„˜๊ธธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ.
→ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋„˜๊ธฐ๋ ค๋ฉด ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ.


2๏ธโƒฃ pthread_create(&tid, &attr, runner, argv[1]);

๐Ÿ“Œ &tid → ์“ฐ๋ ˆ๋“œ ID ์ €์žฅํ•  ๊ณต๊ฐ„์„ ์ „๋‹ฌ

  • tid๋Š” ์“ฐ๋ ˆ๋“œ ID๋ฅผ ์ €์žฅํ•  ๋ณ€์ˆ˜.
  • pthread_create()๋Š” ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ๊ทธ ์“ฐ๋ ˆ๋“œ์˜ ID๋ฅผ tid์— ์ €์žฅํ•ด์•ผ ํ•จ.
  • ํ•˜์ง€๋งŒ C์—์„œ ํ•จ์ˆ˜๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ’์„ ๋ณต์‚ฌํ•ด์„œ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—,
    ๊ฐ’์„ ์ €์žฅํ•˜๋ ค๋ฉด ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๋„˜๊ฒจ์•ผ ํ•ด.
  • ๊ทธ๋ž˜์„œ &tid๋ฅผ ๋„˜๊ฒจ์„œ tid ๋ณ€์ˆ˜ ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผ ํ•จ.

๐Ÿ“Œ &attr → ์“ฐ๋ ˆ๋“œ ์†์„ฑ ๊ตฌ์กฐ์ฒด ์ „๋‹ฌ

  • pthread_attr_t๋Š” ์“ฐ๋ ˆ๋“œ ์†์„ฑ(์Šคํƒ ํฌ๊ธฐ, ์šฐ์„ ์ˆœ์œ„ ๋“ฑ)์„ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ์ฒด.
  • pthread_attr_init(&attr);์—์„œ ์†์„ฑ์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ ํ›„, pthread_create()์— ํฌ์ธํ„ฐ(&attr)๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•จ.
  • ๊ทธ๋ž˜์•ผ pthread_create() ํ•จ์ˆ˜๊ฐ€ attr์„ ์ง์ ‘ ์ฝ์„ ์ˆ˜ ์žˆ์Œ.

๐Ÿ’ก ์™œ ์ฃผ์†Œ๋ฅผ ๋„˜๊ธธ๊นŒ?

  • C ์–ธ์–ด์—์„œ ๊ตฌ์กฐ์ฒด๋ฅผ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋ฉด ๊ฐ’์ด ๋ณต์‚ฌ๋จ.
  • ๋ณต์‚ฌ๋ณธ์„ ์ „๋‹ฌํ•˜๋ฉด ์›๋ณธ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์›๋ณธ์„ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ฃผ์†Œ๋ฅผ ๋„˜๊ฒจ์•ผ ํ•จ.

3๏ธโƒฃ argv[1]์€ ์™œ ๊ทธ๋ƒฅ ๋„˜๊ธฐ๋‚˜?

  • argv[1]์€ ๋ฌธ์ž์—ด(char *)์ด๊ธฐ ๋•Œ๋ฌธ์—, ์›๋ž˜๋ถ€ํ„ฐ ํฌ์ธํ„ฐ ํ˜•ํƒœ์•ผ.
  • ๊ทธ๋ž˜์„œ ๊ตณ์ด &argv[1]์„ ๋„˜๊ธธ ํ•„์š” ์—†์ด, ๊ทธ๋ƒฅ argv[1]์„ ์ „๋‹ฌํ•˜๋ฉด ๋จ.

3.2 Pthreads ์‹ค์Šต 2: Thread์™€ fork()๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

#include <stdio.h>
#include <unistd.h> //fork(), getpid() ์‚ฌ์šฉ
#include <wait.h>
#include <pthread.h>

int value = 0; //์ „์—ญ๋ณ€์ˆ˜, ๋ชจ๋“  ํ•จ์ˆ˜์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ
void * runner(void *param);

int main(int argc, char *argcv[])
{
    pid_t pid; //fork()๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค ID๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜.
    pthread_t tid; //์“ฐ๋ ˆ๋“œ ID๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜.
    pthread_attr_t attr; //์“ฐ๋ ˆ๋“œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ์ฒด.

    pid = fork(); //์ž์‹ ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ 

    if(pid ==0) { //child process
        pthread_attr_init(&attr);
        pthread_create(&tid, &attr, runner, NULL); //์“ฐ๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰
        pthread_join(tid, NULL); //์“ฐ๋ ˆ๋“œ ์ข…๋ฃŒ๊นŒ์ง€ ๋Œ€๊ธฐ
        printf("CHILD: value = %d\n", value);
    }
    else if (pid > 0) { //parent process
        wait(NULL); //์ž์‹ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ๊นŒ์ง€ ๋Œ€๊ธฐ
        printf("PARENT: value = %d\n", value); //์ž์‹ ํ”„๋กœ์„ธ์Šค ๋๋‚˜๋ฉด ์ถœ๋ ฅ
    }
}

void *runner(void *param)
{
    value = 5;
    pthread_exit(0);
}

์‹คํ–‰ ์˜ˆ์‹œ

CHILD: value = 5
PARENT: value = 0โ€‹

์‹คํ–‰ ๊ฒฐ๊ณผ ๋ถ„์„

  • ์ž์‹ ํ”„๋กœ์„ธ์Šค์—์„œ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ value ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด, ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • fork() ์ดํ›„ ์ƒ์„ฑ๋œ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ€์ง€๋ฏ€๋กœ, ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ณ€๊ฒฝํ•œ ๊ฐ’์ด ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์—๋Š” ๋ฐ˜์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ๊ฐœ๋…: Thread์™€ Process์˜ ์ฐจ์ด

  • Thread๋Š” ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
  • Process๋Š” ๋…๋ฆฝ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ, ํ•œ ํ”„๋กœ์„ธ์Šค์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

3.3 Pthreads ์‹ค์Šต 3: fork()์™€ Thread ์ƒ์„ฑ

#include <stdio.h>
#include <unistd.h>
#include <wait.h>
#include <pthread.h>

void *runner(void *param);

int main(int argc, char *argv[])
{
    pid_t pid;
    pthread_t tid;

    printf("A = %d\n", getpid());
    pid = fork(); //์ฒซ ๋ฒˆ์งธ fork ์‹คํ–‰, ์ž์‹์˜ pid ๋ฐ˜ํ™˜
    if(pid > 0) {
        wait(NULL); //์ž์‹ ์ข…๋ฃŒ๊นŒ์ง€ ๋Œ€๊ธฐ
        printf("B = %d\n", pid);
    }
    if(pid == 0) { //์ž์‹ ํ”„๋กœ์„ธ์Šค
        pid = fork();
        if(pid > 0) { //๋‹ค์‹œ fork
            wait(NULL); //์ฒซ ๋ฒˆ์งธ ์ž์‹ ๋Œ€๊ธฐ
            if (pid > 0) printf("C = %d\n", pid);
        }
        pthread_create(&tid, NULL, runner, NULL); //๋‘ ๋ฒˆ์งธ ์ž์‹ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ, runner ์‹คํ–‰
    }
    pid = fork(); //๋ชจ๋“  ํ”„๋กœ์„ธ์Šค์—์„œ fork ์‹คํ–‰
    if(pid > 0) {
        wait(NULL);
        if (pid > 0) printf("D = %d\n", pid);
    }
}

void *runner(void *param)
{
    printf("I'm a thread!\n");
    pthread_exit(0);
}

์‹คํ–‰ ์˜ˆ์‹œ

A = 9332
I'm a thread!
D = 9336
C = 9334
I'm a thread!
D = 9338
B = 9333
D = 9339

๋ถ„์„

์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ, fork()์™€ pthread_create()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค

์™€ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

pid_t pid;

pid = fork();
if(pid == 0) { /* child process */
    fork();
    pthread_create(...);
}
fork();

ํ”„๋กœ์„ธ์Šค ๋ฐ ์“ฐ๋ ˆ๋“œ ๊ฐœ์ˆ˜ ๋ถ„์„

a. Unique Process ๊ฐœ์ˆ˜: 6๊ฐœ

b. Unique Thread ๊ฐœ์ˆ˜: 2๊ฐœ

๊ณผ์ • ์„ค๋ช…

  1. A (๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค)๊ฐ€ B (์ž์‹ ํ”„๋กœ์„ธ์Šค)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. B๊ฐ€ fork()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ C๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. B์™€ C๋Š” ๊ฐ๊ฐ pthread_create()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  "I'm a thread!"๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  4. ์ดํ›„ A, B, C ๋ชจ๋‘ fork()๋ฅผ ์‹คํ–‰ํ•˜์—ฌ D, D, D ํ”„๋กœ์„ธ์Šค(์ด 3๊ฐœ)๋ฅผ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด ์‹ค์Šต์„ ํ†ตํ•ด fork()์™€ pthread_create()์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ดํ•ดํ•˜๊ณ , ํ”„๋กœ์„ธ์Šค์™€ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ์„ฑ๋˜๋Š”์ง€ ์‹ค์Šตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

4. Implicit Threading

์“ฐ๋ ˆ๋“œ์˜ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด Implicit Threading ๊ธฐ๋ฒ•์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ๊ธฐ๋ฒ•์œผ๋กœ๋Š” ๋‹ค์Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • Thread Pools: ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋œ ์“ฐ๋ ˆ๋“œ ํ’€์—์„œ ์“ฐ๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹.
  • Fork & Join Model: ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๋ฐฉ์‹.
  • OpenMP: ์ปดํŒŒ์ผ๋Ÿฌ ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„.

4.1 OpenMP ์‹ค์Šต 1: ๊ธฐ๋ณธ์ ์ธ ๋ณ‘๋ ฌ ์‹คํ–‰

#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[])
{
    #pragma omp parallel
    {
        printf("I am a parallel region.\n");
    }
    return 0;
}

์‹คํ–‰ ๋ฐฉ๋ฒ•

gcc -fopenmp openmp_example1.c -o openmp_example1
./openmp_example1

4.2 OpenMP ์‹ค์Šต 2: ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ ํ™œ์šฉ

 

#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[])
{
    omp_set_num_threads(4);

    #pragma omp parallel
    {
        printf("OpenMP thread: %d\n", omp_get_thread_num());
    }

    return 0;
}

์‹คํ–‰ ์˜ˆ์‹œ

OpenMP thread: 1
OpenMP thread: 3
OpenMP thread: 0
OpenMP thread: 2

์“ฐ๋ ˆ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋Š” ๋ณด์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

5. ๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” pthread์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ์‹ค์Šต์„ ์ง„ํ–‰ํ•˜์˜€์œผ๋ฉฐ, fork()์™€์˜ ๊ด€๊ณ„, OpenMP๋ฅผ ํ™œ์šฉํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊นŒ์ง€ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ํ•™์Šต ์ถ”์ฒœ

  • mutex, semaphore๋ฅผ ํ™œ์šฉํ•œ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•
  • pthread_cond_wait() ๋ฐ pthread_cond_signal()์„ ์ด์šฉํ•œ ์กฐ๊ฑด ๋ณ€์ˆ˜
  • ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ธฐ๋ฒ•

์‹ค์Šต์„ ํ†ตํ•ด ์“ฐ๋ ˆ๋“œ์˜ ์ƒ์„ฑ, ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ํ™œ์šฉ, ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์„ ์ตํžˆ๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.