C์—์„œ ์ง€์›ํ•˜๋Š” POSIX thread ์ฒดํ—˜๊ธฐ.

10 minute read

3๋…„๊ฐ„ ์‚ฐ์—…๊ธฐ๋Šฅ์š”์›์œผ๋กœ ๋ณต๋ฌด ํ•˜๊ณ , ๋ณตํ•™ํ•ด ์ปด๊ณต๊ณผ ์ˆ˜์—…์„ ๋“ฃ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ ๋งŽ์ด ๋ฐฐ์› ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์—ฌ์ „ํžˆ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ๋งŽ๋„ค์š” ^^;; ์—ญ์‹œ ์„ธ์ƒ๋„ ๋„“๊ณ  ๊ณต๋ถ€์˜ ๊ธธ๋„ ๋„“์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋“ค์–ด๊ฐ€๋ฉฐ

ํ•™๊ต ์šด์˜์ฒด์ œ ์ˆ˜์—…์˜ ๊ฐ•์˜ ์Šฌ๋ผ์ด๋“œ์— โ€œ์š”๊ฒŒ thread๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ ์˜ˆ์‹œ์—์š”^^โ€๋ผ๋ฉฐ ์ฝ”๋“œ ์กฐ๊ฐ์ด ๋ฉ๊ทธ๋Ÿฌ๋‹ˆ ์žˆ์—ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‚˜์˜ ๊ฐ์ข… ์ž๊ฒฉ์ฆ ์‹œํ—˜๊ณผ ์ฝ”ํ…Œ ๊ฒฝํ—˜์— ๋ฏธ๋ฃจ์–ด๋ดค์„ ๋•Œ, ์ฝ”๋“œ๋ฅผ ๊ทธ๋ƒฅ ์ฝ๋Š” ๊ฑด ๋จธ๋ฆฟ์†์— ์ž˜ ๋‚จ์ง€ ์•Š์•˜์—ˆ๋‹ค;; ๊ทธ๋ž˜์„œ ๊ฐ•์˜ ์Šฌ๋ผ์ด๋“œ์— ๋‚˜์˜จ ์ฝ”๋“œ ์กฐ๊ฐ๋“ค์„ C๋กœ ์˜ฎ๊ฒจ์„œ ์ง์ ‘ ์งœ๋ณด๋ ค๊ณ  ํ•œ๋‹ค!!

์š”๊ฒŒ ์›๋ž˜ ๊ฐ•์˜ ์Šฌ๋ผ์ด๋“œ์— ์žˆ๋˜ ์ฝ”๋“œ ์˜ˆ์‹œ์ด๋‹ค. C์–ธ์–ด์™€ ๋น„์Šทํ•˜์ง€๋งŒ, ์™„์ „ํžˆ ๋™์ผํ•˜์ง„ ์•Š๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŠธ์˜ ๋ชฉํ‘œ๋Š” ์•„๋ž˜ ํ•จ์ˆ˜๋“ค์„ ๊ฒฝํ—˜ํ•ด๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

  • thread_create()
  • thread_exit()
  • thread_join()

Hello, pthread!

์ œ์ผ ๋จผ์ € pthread_create()์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

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

#define NTHREADS 10

pthread_t threads[NTHREADS];

๊ทธ์ „์— ๋จผ์ € pthread ์‚ฌ์šฉ์„ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ pthread.h๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ๊ฐ์ข… ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด๋‘”๋‹ค. pthread_t๋Š” pthread ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๊ตฌ์กฐ์ฒด์ด๋‹ค. ์•ž์— โ€œpโ€๊ฐ€ ๋ถ™๋Š” ์ด์œ ๋Š” POSIX์—์„œ ์š”๊ตฌํ•˜๋Š” ์“ฐ๋ ˆ๋“œ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ”์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ํ•œ๋‹ค.

Callee Function

void* go (void* args) {
  int* n = (int*) args;
  printf("Hello from thread %d\n", *n);
}

์ผ๋‹จ ์“ฐ๋ ˆ๋“œ๋กœ ์‹คํ–‰์‹œํ‚ฌ go()๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๋Š” ๋ฆฌํ„ด๊ณผ ํ•จ์ˆ˜ ์ธ์ž๊ฐ€ ๋‘˜๋‹ค void* ํƒ€์ž…์ด๋‹ค. void* ํƒ€์ž…์„ ์ฒ˜์Œ ๋งˆ์ฃผํ•˜์—ฌ ์–ด์ƒ‰ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฒจ์–ธํ•˜์ž๋ฉดโ€ฆ (๋ณธ์ธ๋„ void* ํƒ€์ž…์€ ์ด๋ฒˆ์— OS ๋“ค์œผ๋ฉด์„œ ์ฒ˜์Œ ๋ดค๋‹ค ใ…‹ใ…‹)

int ํƒ€์ž…๊ณผ char ํƒ€์ž…์€ ๊ฐ๊ฐ 4 byte์™€ 1 byte๋กœ ๋‹ค๋ฅธ ์‚ฌ์ด์ฆˆ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋Š” ๋ชจ๋‘ ์ฐธ๊ณ ํ•˜๋Š” ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๊ฐ’(address)๋ฅผ ๋‹ด๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋‘ 4 bytes ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋“  ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋Š” ์‚ฌ์‹ค ๊ฐ™์€ ํƒ€์ž…์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ int*, char*๋กœ ํƒ€์ž…์„ ๊ณ๋“ค์—ฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋ƒ?๋ผ๊ณ  ์˜๋ฌธ์„ ์ œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ์ €๊ธฐ์— ๋ถ™๋Š” int์™€ char๋Š” ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ๋งํ•  ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋„ ์œ ํšจํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

int a = 10;
char* p = (char*) &a;

(char*)๋ผ๊ณ  ํฌ์ธํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•œ ์บ์ŠคํŒ…์ด ๋“ค์–ด๊ฐ€์ง€๋งŒ, int ๋ณ€์ˆ˜์˜ ์ฃผ์†Ÿ๊ฐ’์ด long* ํƒ€์ž… ํฌ์ธํ„ฐ์˜ ๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ€๋Š”๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

void*๋Š” ์ด๋Ÿฐ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜์˜ ํŠน์„ฑ์„ ํ™œ์šฉํ•ด, ์•„์˜ˆ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ int*๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๊ณ , float*๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๊ณ , ๊ทธ ์–ด๋–ค ํฌ์ธํ„ฐ ํƒ€์ž…๋„ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”๊ฑธ โ€œvoid ํฌ์ธํ„ฐโ€๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

void ํฌ์ธํ„ฐ๋ฅผ ์“ฐ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

int a = 10;
void* p = &a;
*((int*) p) = 20;

๋งŒ์•ฝ ํƒ€์ž… ์บ์ŠคํŒ… ์—†์ด *p = 20;๋กœ ์“ฐ๋ ค๊ณ  ํ•œ๋‹ค๋ฉด, void ํฌ์ธํ„ฐ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์–ด๋–ค ์‚ฌ์ด์ฆˆ์ธ์ง€ ๋ชฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๋ฅผ RW ํ•  ์ˆ˜ ์—†์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ (int*) ์บ์ŠคํŒ…์„ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

pthread_create

์ด์ œ main ํ•จ์ˆ˜์—์„œ pthread_create()๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ž.

int main(void) {
  int thread_args[NTHREADS];

  for (int i=0; i < NTHREADS; i++) {
    thread_args[i] = i;
    pthread_create(&threads[i], NULL, go, &thread_args[i]);
  }

  return 0;
}

pthread_create(&threads[i], NULL, go, &thread_args[i])์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์˜€๋Š”๋ฐ, ๊ฐ ์ธ์ž์˜ ์˜๋ฏธ๋ฅผ ์ ์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค. ๋ช…์„ธ๋Š” linux man page๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.

  • pthread_t *restrict thread
    • pthread_t ํฌ์ธํ„ฐ ๋ณ€์ˆ˜
    • restrict๋Š” ๊ทธ ํฌ์ธํ„ฐ๊ฐ€ ์ฐธ๊ณ ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋‹ค๋ฅธ ํฌ์ธํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฑธ ๋งํ•œ๋‹ค. C์–ธ์–ด ์ปดํŒŒ์ผ ๋•Œ ์ตœ์ ํ™”์— ์‚ฌ์šฉํ•˜๋Š” ํ‚ค์›Œ๋“œ๋‹ค.
  • const pthread_attr_t *restrict attr
    • ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์“ฐ๋ ˆ๋“œ์˜ ํŠน์„ฑ๊ฐ’(attribution)์„ ์ •์˜ํ•œ๋‹ค.
    • ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์„œ NULL๋กœ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.
  • void *(*start_routine)(void *)
    • ์“ฐ๋ ˆ๋“œ๋กœ ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ธ์ž์™€ ๋ฆฌํ„ด ํƒ€์ž…์ด ๋‘˜๋‹ค void*์—ฌ์•ผ ํ•œ๋‹ค.
  • void *restrict arg
    • start_routine ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ํ•จ์ˆ˜ ์ธ์ž๋ฅผ ์ •์˜ํ•œ๋‹ค. ์š”๊ฒƒ๋„ ํฌ์ธํ„ฐ๋กœ ์ „๋‹ฌํ•œ๋‹ค!

์ด๋ ‡๊ฒŒ ์ •์˜ํ•œ ์ƒํƒœ์—์„œ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผ ํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณด๋ฉด,

$ gcc threadHello.c
$ ./a.out
Hello from thread 0
Hello from thread 1
Hello from thread 7
Hello from thread 3

์‘?? 10๊ฐœ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“œ๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, 4๊ฐœ ์ •๋„ ๋งŒ๋“ค๊ณ  ์‹คํ–‰์ด ์ข…๋ฃŒ ๋˜์—ˆ๋‹ค ๐Ÿค” ๊ทธ ์ด์œ ๋Š” Thread Join์„ ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋–„๋ฌธ์ด๋‹ค!!

Argument passing

Thread create ๋•Œ, ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ์“ฐ๋ ˆ๋“œ๋กœ ์‹คํ–‰ํ• ์ง€๋„ ์ „๋‹ฌํ•˜์ง€๋งŒ, ๊ทธ ํ•จ์ˆ˜์— ์–ด๋–ค ์ธ์ž๋กœ ์‹คํ–‰ํ• ์ง€๋„ void* args ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•œ๋‹ค.

void* go (void* args) {
  int* n = (int*) args; // get value from args
  printf("Hello from thread %d\n", *n);
}

int main(void) {
  int thread_args[NTHREADS];

  for (int i=0; i < NTHREADS; i++) {
    thread_args[i] = i;
    pthread_create(&threads[i], NULL, go, &thread_args[i]); // pass args
  }

  return 0;
}

์—ฌ๊ธฐ ์ฝ”๋“œ์—์„œ๋Š” ์ •์ˆ˜๊ฐ’ i์˜ ๊ฐ’์„ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๋ ค๊ณ  ํ•œ๋‹ค. ์ด๋•Œ, &i๋กœ ๋ฐ”๋กœ ๋„˜๊ธฐ์ง€ ์•Š๊ณ , thread_args[i]์— ๋‹ด์•„์„œ ๊ฐ’์„ ์ „๋‹ฌํ–ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” &i๋กœ ๋ฐ”๋กœ ๋„˜๊ธฐ๋ฉด, i ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ์—์„œ ์ ‘๊ทผํ•˜๋Š” ๊ผด์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

pthread_join

int main(void) {
  // Thread Create
  ...

  for (int i=0; i < NTHREADS; i++) {
    pthread_join(threads[i], NULL);
    printf("Thread %d returned\n", i);
  }
  printf("Main thread done\n");
}

pthread_join()๋„ ์–ด๋–ค ์“ฐ๋ ˆ๋“œ์˜ signal์„ ๋ฐ›์„ ๊ฑด์ง€ ์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

  • pthread_t thread
    • ์•ž์—์„œ pthread_create() ๋•Œ๋Š” pthread_t์˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉ ํ–ˆ๋Š”๋ฐ, join์—์„œ๋Š” ์“ฐ๋ ˆ๋“œ ๋ณ€์ˆ˜ ๊ทธ ์ž์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • void **retval
    • ๋’ค์—์„œ ๋‹ค๋ฃฐ ๊ฑฐ์ง€๋งŒ, pthread_exit()์œผ๋กœ ๋ถ€๋ชจ ์“ฐ๋ ˆ๋“œ์—๊ฒŒ signal์„ ์ค„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ทธ๋–„ ์ „๋‹ฌ ๋ฐ›์€ ๊ฐ’์„ ๊ธฐ๋กํ•˜๊ธฐ ์œ„ํ•œ ์ธ์ž์ด๋‹ค.
    • ์ง€๊ธˆ์€ NULL์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ๊ณง ๋’ค์—์„œ retval์„ ์“ฐ๋Š” ์˜ˆ์‹œ๋„ ๋ณผ ์˜ˆ์ •!

๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผ ํ•ด์„œ ์‚ดํŽด๋ณด๋ฉดโ€ฆ

$ ...
Hello from thread 0
Hello from thread 4
Hello from thread 6
Hello from thread 8
Hello from thread 1
Hello from thread 5
Hello from thread 2
Hello from thread 7
Hello from thread 3
Hello from thread 9
Thread 0 returned
Thread 1 returned
Thread 2 returned
...
Thread 7 returned
Thread 8 returned
Thread 9 returned
Main thread done

์ด๋ฒˆ์—๋Š” ์ƒ์„ฑํ•œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ชจ๋‘ ์‹คํ–‰๋˜์—ˆ๋‹ค!! ์‹คํ–‰ ์ˆœ์„œ๋Š” ์ œ๊ฐ๊ฐ์ด์ง€๋งŒ, pthread_join() ํ›„์— printf() ์ถœ๋ ฅ ๋˜๋Š” ๊ฑด ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰๋œ๋‹ค!

์“ฐ๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ ๋œ ํ›„, ์‹คํ–‰์€ ๋™์‹œ์— ์ง„ํ–‰๋œ๋‹ค. ์‹คํ–‰ ๊ณผ์ •์—์„œ์˜ ์ˆœ์„œ๋Š” ์ •ํ•ด์ง„ ๋ฐ”๊ฐ€ ์—†๋‹ค. ๋‹ค๋งŒ, pthread_join()์œผ๋กœ ์ข…๋ฃŒ signal์„ ๋ฐ›๊ธฐ ์ „์—” ์“ฐ๋ ˆ๋“œ์˜ ์ž์›์ด ํ•ด์ œ ๋˜์ง€ ์•Š๊ณ  ๋‚จ์•„์žˆ๋‹ค. ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์šด์˜ํ•  ๋•Œ๋„ wait์œผ๋กœ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ signal์„ ๊ผญ ๋ฐ›์•„์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด zombie process1์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์“ฐ๋ ˆ๋“œ๋ฅผ ์šด์˜ํ•  ๋•Œ๋„ ๋น„์Šทํ•˜๋‹ค. ๊ผญ join์„ ํ†ตํ•ด ์ž์‹ ์“ฐ๋ ˆ๋“œ์˜ signal์„ ๋ฐ›๊ณ , ์ž์‹ ์“ฐ๋ ˆ๋“œ๋ฅผ ํ• ๋‹น ํ•ด์ œ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•œ๋‹ค.

pthread_exit

์ด๋ฒˆ์—๋Š” ์ž์‹ ์“ฐ๋ ˆ๋“œ์—์„œ pthread_exit()์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒํ•˜๋ฉด์„œ, ๋ถ€๋ชจ ์“ฐ๋ ˆ๋“œ์—๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด์ž.

void* go (void* args) {
  int* n = (int*) args;
  printf("Hello from thread %d\n", *n);
  *n += 100;
  pthread_exit(n); // return value to parent thread
}

int main(void) {
  // Thread Create
  ...

  for (int i=0; i < NTHREADS; i++) {
    void* return_value; // pointer to get returned value
    pthread_join(threads[i], &return_value);
    printf("Thread %d returned %d\n", i, *((int*) return_value));
  }
  printf("Main thread done\n");
  return 0;
}

์ฃผ๋ชฉํ•  ๋ถ€๋ถ„์€ pthread_exit(n); ๋ถ€๋ถ„๊ณผ pthread_join(threads[i], &return_value); ๋ถ€๋ถ„์ด๋‹ค.

์ž์‹ ์“ฐ๋ ˆ๋“œ๋Š” pthread_exit(n)์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒํ•˜๋ฉฐ, ๋ถ€๋ชจ ์“ฐ๋ ˆ๋“œ์—๊ฒŒ ๊ฐ’์„ ๋„˜๊ฒจ์ค€๋‹ค. ์ด๋•Œ, ๊ฐ’ ์ž์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ int* n์„ ๋„˜๊ฒจ์ค€๋‹ค.

๋ถ€๋ชจ ์“ฐ๋ ˆ๋“œ๋Š” pthread_join()์œผ๋กœ ์ž์‹ ์“ฐ๋ ˆ๋“œ์˜ ์ข…๋ฃŒ ์ƒํƒœ๋ฅผ ํšŒ์ˆ˜ํ•œ๋‹ค. ์ด๋•Œ, void* return_value๋ฅผ ์‚ฌ์šฉํ•ด ํ•ด๋‹น ๊ฐ’์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•˜๋Š”๋ฐ, ์ข…๋ฃŒ ์ƒํƒœ๋ฅผ ๊ธฐ๋กํ•  ์ฃผ์†Œ ์œ„์น˜ ๋ฐ›์•„์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ &return_value๋กœ ์‚ฌ์šฉํ•œ ๊ฒƒ.

References

  1. ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค ๋ณด๋‹ค ๋จผ์ € ์ข…๋ฃŒ ๋˜์—ˆ์ง€๋งŒ, ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๊ฐ€ wait์œผ๋กœ ์ข…๋ฃŒ ์ƒํƒœ๋ฅผ ํšŒ์ˆ˜ ํ•˜์ง€ ์•Š์€ ์ƒํƒœย