728x90
쓰레드 관련 함수
- 쓰레드 생성 : pthread_create
-> 성공 시 0, 실패 시 0이외의 값 반환
-> thread : 생성할 쓰레드의 ID 저장을 위한 변수의 주소값
-> attr : 특성 정보
-> start_routine : 별도의 실행 흐름이 되는 함수 포인터
-> arg : 호출될 함수에 전달할 매개 변수
#include <pthread.h>
int pthread_create( pthread_t *restrict thread, const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void* restrict arg);
- 쓰레드 종료의 대기 : pthread_join
-> 메인 쓰레드가 종료되면 생성한 쓰레드가 종료되기 때문에 쓰레드가 종료될 때 까지 대기해야 함
-> 성공 시 0, 실패 시 0이외의 값 반환
-> thread : 쓰레드 ID 전달
-> status : 반환 값
#include <pthread.h>
int pthread_join(pthread_t thread, void **status);
- 쓰레드가 소멸되면 스택영역은 소멸되기때문에 서로 공유하고 있는 힙영역이나 데이터 영역을 사용해야 하기 때문에 malloc사용
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
void* thread_main(void *arg);
int main(int argc, char *argv[])
{
pthread_t t_id;
int thread_param=5;
void * thr_ret;
if(pthread_create(&t_id, NULL, thread_main, (void*)&thread_param)!=0)
{
puts("pthread_create() error");
return -1;
};
if(pthread_join(t_id, &thr_ret)!=0)
{
puts("pthread_join() error");
return -1;
};
printf("Thread return message: %s \n", (char*)thr_ret);
free(thr_ret);
return 0;
}
void* thread_main(void *arg)
{
int i;
int cnt=*((int*)arg);
char * msg=(char *)malloc(sizeof(char)*50);
strcpy(msg, "Hello, I'am thread~ \n");
for(i=0; i<cnt; i++)
{
sleep(1); puts("running thread");
}
return (void*)msg;
}
쓰레드에 안전한 함수
- 프로세스 내에서 쓰레드는 함수에 동시에 접근할 수 있음
- 둘 이상의 쓰레드가 동시에 접근하면 문제가 생길 수 있는데 이런 문제를 일으키지 않는 함수를 쓰레드에 안전한 함수라고 함
- 헤더파일 선언 이전에 _REENTRANT 매크로를 정의하거나 컴파일 시 옵션으로 주면 불안전한 함수의 호출문을 안전한 함수의 호출문으로 자동으로 변경됨
gcc -D_REENTRANT test.c -o test -lpthread
워커 쓰레드 모델
- 메인 쓰레드가 일을 담당할 쓰레드를 생성하여 결과를 받아 처리하는 모델
#include <stdio.h>
#include <pthread.h>
void * thread_summation(void * arg);
int sum=0; // 세 쓰레드가 공유하는 전역 영역
int main(int argc, char *argv[])
{
pthread_t id_t1, id_t2;
int range1[]={1, 5};
int range2[]={6, 10};
pthread_create(&id_t1, NULL, thread_summation, (void *)range1);
pthread_create(&id_t2, NULL, thread_summation, (void *)range2);
pthread_join(id_t1, NULL);
pthread_join(id_t2, NULL);
printf("result: %d \n", sum);
return 0;
}
void * thread_summation(void * arg)
{
int start=((int*)arg)[0];
int end=((int*)arg)[1];
while(start<=end)
{
sum+=start;
start++;
}
return NULL;
}
- 하나의 전역 변수를 둘 이상의 쓰레드가 접근하기 때문에 문제가 될 수 있음
728x90
'Programming > Network' 카테고리의 다른 글
열혈 TCP/IP 18-4. 쓰레드 동기화 (0) | 2021.03.28 |
---|---|
열혈 TCP/IP 18-3. 쓰레드의 문제점과 임계영역(Critical Section) (0) | 2021.03.28 |
열혈 TCP/IP 18-1. 쓰레드의 이론적 이해 (0) | 2021.03.28 |
열혈 TCP/IP 17-2. 레벨 트리거와 엣지 트리거 (0) | 2021.03.28 |
열혈 TCP/IP 17-1. epoll의 이해와 활용 (0) | 2021.03.28 |