📌 매뉴얼 (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 함수이다.
'프로그래밍 > C' 카테고리의 다른 글
[library] atoi 구현하기 (0) | 2025.03.12 |
---|---|
[function] pthread_detach 함수 알아보기 (2) | 2024.09.18 |
[function] pthread_create 함수 알아보기 (5) | 2024.09.07 |
[utility] get_next_line 구현하기 (3) | 2024.08.31 |
[graphic] miniLibX Manual (0) | 2024.08.06 |