Do You Coding?

[function] pthread_join ํ•จ์ˆ˜ ์•Œ์•„๋ณด๊ธฐ ๋ณธ๋ฌธ

CS & Engineering/C

[function] pthread_join ํ•จ์ˆ˜ ์•Œ์•„๋ณด๊ธฐ

๐Ÿ“Œ ๋งค๋‰ด์–ผ (Linux)

๋”๋ณด๊ธฐ

NAME

      pthread_join - join with a terminated thread

 

SYNOPSIS

       #include <pthread.h>

       int pthread_join(pthread_t thread, void **retval);

       Compile and link with -pthread.

 

DESCRIPTION

       The pthread_join() function waits for the thread specified by thread to terminate.

       If that thread has already terminated, then pthread_join() returns immediately.

       The thread specified by thread must be joinable. If retval is not NULL, then pthread_join()

       copies the exit status of the target thread (i.e., the value that the target thread supplied to

       pthread_exit(3)) into the location pointed to by retval. If the target thread was canceled, then

       PTHREAD_CANCELED is placed in the location pointed to by retval.

       If multiple threads simultaneously try to join with the same thread, the results are undeโ€ fined.

       If the thread calling pthread_join() is canceled, then the target thread will remain joinable

       (i.e., it will not be detached).

 

RETURN VALUE

       On success, pthread_join() returns 0; on error, it returns an error number.

 

ERRORS

       EDEADLK

              A deadlock was detected (e.g., two threads tried to join with each other);

              or thread specifies the calling thread.

       EINVAL

              thread is not a joinable thread.

       EINVAL

              Another thread is already waiting to join with this thread.

       ESRCH

              No thread with the ID thread could be found.

 

๐Ÿ“Œ ํ•จ์ˆ˜ ์„ค๋ช…

์ด์ „ pthread_create ํ•จ์ˆ˜์— ์ด์–ด, ์Šค๋ ˆ๋“œ ๊ด€๋ จ ํ•จ์ˆ˜์ธ pthread_join ํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ pthread.h ๋ฅผ include ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,

์ด ํ•จ์ˆ˜๋Š” ์„œ๋ธŒ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋‹ค.

 

๋‹จ์ˆœํžˆ main๋ฌธ์—์„œ pthread_create๋ฅผ ์ด์šฉํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ์„๋•Œ,

๋งŒ๋“  ์Šค๋ ˆ๋“œ๋ฅผ '์„œ๋ธŒ ์Šค๋ ˆ๋“œ', main๋ฌธ์„ '๋ฉ”์ธ ์Šค๋ ˆ๋“œ' ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ, sleep์ฒ˜๋Ÿผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ถ€๋ถ„์„ main์—์„œ ๋งŒ๋“ค์ง€ ์•Š์•˜๋‹ค๋ฉด,

ํ•ด๋‹น ์„œ๋ธŒ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ค ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ณ  ์ข…๋ฃŒ๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ,

์ด ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์„œ๋ธŒ ์Šค๋ ˆ๋“œ์˜ ๊ฒฐ๊ณผ์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ข…๋ฃŒ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋กœ pthread_join์ด ์“ฐ์ธ๋‹ค.

๋˜ํ•œ, ์ข…๋ฃŒ๋ฅผ ๋Œ€๊ธฐํ•˜๋ฉด์„œ ์„œ๋ธŒ ์Šค๋ ˆ๋“œ์˜ ๋ฆฌํ„ด ๊ฐ’๋„ ๋ฐ›์•„ ์ฒ˜๋ฆฌ๋„ ํ•ด์ค€๋‹ค.

 

int pthread_join(pthread_t thread, void **retval);

ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž.

 

pthread_t thread : ์ข…๋ฃŒ๋ฅผ ๋Œ€๊ธฐํ•˜๊ณ , ๋ฆฌํ„ด ๊ฐ’์„ ๋ฐ›์„ ์Šค๋ ˆ๋“œ์˜ ID ๊ฐ’์ด๋‹ค.

pthread_create()๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๋‚˜์˜จ ํ•ด๋‹น ID ๊ฐ’์„ ๋Œ€์ž…ํ•˜๋ฉด ๋œ๋‹ค.

void **retval : ์Šค๋ ˆ๋“œ์—์„œ ๋ฆฌํ„ด๊ฐ’์„ ๊ธฐ๋ณธ์ ์œผ๋กœ void * ํ˜•์‹์œผ๋กœ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋˜๋Š”๋ฐ,

์ด ๊ฐ’์„ call by reference ๋กœ ์ฃผ์†Œ ๊ฐ’์„ ๋ฐ›์•„ ๊ฐ€์ ธ์˜จ๋‹ค.

(void ํ˜•์‹์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์บ์ŠคํŒ…ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.)

 

๊ทธ๋ฆฌ๊ณ  pthread_join์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ์„ฑ๊ณต์‹œ 0 / ์‹คํŒจ์‹œ Error number๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ถ”๊ฐ€์ ์œผ๋กœ, ํ”„๋กœ์„ธ์Šค์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ, ์ด pthread_join ํ•จ์ˆ˜๋Š” wait ๊ณ„์—ด์˜ ํ•จ์ˆ˜์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.

(wait : ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ ์ข…๋ฃŒ๋ฅผ ๋Œ€๊ธฐํ•œ๋‹ค.)

 

 

 

pthread_create ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์‹œ๋ฅผ ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด๋ณด์ž.


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

void    *thread_func(void *arg)
{
    int i = *((int*) arg);
    int c = *((int*) arg) + 5;
    
    while(i <= c)
    {
        sleep(1);
        printf("running thread %d\n", i);
        i ++;
    }
    return (NULL);
}

int main(void)
{
    pthread_t   thread_ID;
    int         arg = 0;

    if(pthread_create(&thread_ID, NULL, thread_func, (void *)&arg) != 0)
        exit(1);
    //pthread_join(thread_ID, NULL);
    printf("end\n");
    return (0);
}

 

์ถœ๋ ฅ - std_output)

 

์œ„์˜ ์ฝ”๋“œ๋Š” main์—์„œ pthread_create ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๊ณ , ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ main ์Šค๋ ˆ๋“œ์—์„œ๋Š” ํ•ด๋‹น ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ถ€๋ถ„์ด ์กด์žฌํ•˜์ง€ ์•Š๊ณ ,

thread_func์ด ์‹คํ–‰๋˜์ง€ ๋ชปํ•˜๊ณ  ๋ฐ”๋กœ end๋งŒ ์ถœ๋ ฅํ•˜๊ณ  main ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ฒŒ ๋œ๋‹ค.

 

์ด์ „์˜ pthread_create ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” sleep์„ ํ†ตํ•ด์„œ main ์Šค๋ ˆ๋“œ ์ข…๋ฃŒ๋ฅผ ๋ง‰์•„์คฌ์ง€๋งŒ,

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” ๊ทธ ๋ถ€๋ถ„์„ ์ง€์› ์œผ๋ฏ€๋กœ main ์Šค๋ ˆ๋“œ๊ฐ€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์—†๋Š” ์ƒํƒœ์ด๋‹ค.

 

๊ทธ๋Ÿผ ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌํ•ด๋‘” pthread_join์„ ๋„ฃ์–ด์ค€๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ์‚ดํŽด๋ณด์ž.

 

-> pthread_join(thread_ID, NULL); ๋ถ€๋ถ„ ์ฃผ์„ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์› ์„ ๊ฒฝ์šฐ

 

ํ•จ์ˆ˜ ์‹คํ–‰์ด ์ •์ƒ์ ์œผ๋กœ ๋˜์—ˆ๊ณ , end ๊นŒ์ง€ ์ž˜ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ฒ˜๋Ÿผ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์—ญํ• ์„ ์ž˜ ์ˆ˜ํ–‰ํ•ด์ค€๋‹ค.


#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

void    *thread_func(void *arg)
{
    char*   ret;
    int i = *((int*) arg);
    int c = *((int*) arg) + 5;
    
    while(i <= c)
    {
        sleep(1);
        printf("running thread %d\n", i);
        i ++;
    }
    ret = (char *)malloc(sizeof(char) * 10);
    strcpy(ret, "doyoucode\0");
    return (ret);
}

int main(void)
{
    pthread_t   thread_ID;
    void        *t_return;
    int         arg = 0;

    if(pthread_create(&thread_ID, NULL, thread_func, (void *)&arg) != 0)
        exit(1);
    pthread_join(thread_ID, &t_return);
    printf("end, return value : %s\n", (char *)t_return);
    free(t_return);
    return (0);
}

 

์ถœ๋ ฅ - std_output)

 

์œ„์˜ ์ฝ”๋“œ๋Š” ์Šค๋ ˆ๋“œ์˜ ๋ฆฌํ„ด๊ฐ’์„ ํ™œ์šฉํ•ด๋ณด๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ์ด๋‹ค.

์šฐ์„  main์—์„œ t_return์ด๋ผ๋Š” ๋ฆฌํ„ด๊ฐ’์„ ๋ฐ›์„ ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ํ•ด๋‹น ๋ณ€์ˆ˜๋Š”

pthread_join์˜ ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ž๋ฆฌ์— ์ฃผ์†Œ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•ด์ค€๋‹ค.

 

๊ทธ๋Ÿผ ์ด์ œ ์‹คํ–‰๋œ thread_func์—์„œ char * ๋ณ€์ˆ˜๋กœ ์ƒ์„ฑ๋œ ๊ฐ’์ด ๋ฐ˜ํ™˜์ด ๋˜๊ณ ,

ํ•ด๋‹น ๋ฐ˜ํ™˜์ด pthread_join์— ์˜ํ•ด t_return์— ์ €์žฅ๋˜๊ณ  ํ•ด๋‹น ๊ฐ’์„ printf๋กœ ์ถœ๋ ฅํ•  ๋•Œ๋Š” void * ์ธ ๋ณ€์ˆ˜๋ฅผ

char * ๋กœ type casting ํ•ด์ฃผ์–ด ์ถœ๋ ฅํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฐ์‹์œผ๋กœ ์Šค๋ ˆ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” pthread_join ํ•จ์ˆ˜์ด๋‹ค.