멀티프로세스 기반 단점
쓰레드
프로세스 : 운영체제 관점에서 별도의 실행흐름을 구성하는 단위
쓰레드 : 프로세스 관점에서 별도의 실행흐름을 구성하는 단위
POSIX(Portable Operating System Interface for Computer Environment)
: UNIX 계열 운영체제 간에 이식성을 높이기 위한 표준 API 규격.
쓰레드 생성 방식도 POSIX 표준 근거.
쓰레드는 별도 실행흐름을 갖기 때문에, 쓰레드만의 main 함수 필요
pthread_create() : 특정 함수를 시작으로 별도 실행흐름 형성할 것을 운영체제에 요청
int main(int argc, char *argv[])
{
pthread_t t_id;
int thread_param=5;
if(pthread_create(&t_id, NULL, thread_main, (void*)&thread_param)!=0)
{
puts("pthread_create() error");
return -1;
};
sleep(10); puts("end of main");
return 0;
}
void* thread_main(void *arg)
{
int i;
int cnt=*((int*)arg);
for(i=0; i<cnt; i++)
{
sleep(1); puts("running thread");
}
return NULL;
}

지금처럼 쓰레드 끝날 때까지 sleep()하는 건 비현실적
pthread_join() : 인자로 전달된 쓰레드가 종료될 때까지, 해당 함수 호출한 프로세스(또는 쓰레드) 대기상태에 둔다.
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);
임계 영역 : 둘 이상의 쓰레드가 동시에 실행하면 문제 일어나는 문장 존재하는 함수
쓰레드 안전 함수
_r이 붙는다1부터 10까지의 덧셈 결과를 출력하는 프로그램 만들 때,
쓰레드 두 개가 각각 1~5, 6~10 연산하면 이것을 Worker thread 모델이라 함.
long long num = 0;
int main(int argc, char *argv[])
{
pthread_t thread_id[NUM_THREAD];
int i;
printf("sizeof long long: %d \n", sizeof(long long));
for(i=0; i<NUM_THREAD; i++)
{
if(i%2)
pthread_create(&(thread_id[i]), NULL, thread_inc, NULL);
else
pthread_create(&(thread_id[i]),NULL, thread_des, NULL);
}
for(i=0; i<NUM_THREAD; i++)
pthread_join(thread_id[i], NULL);
printf("result: %lld \n", num);
return 0;
}
void * thread_inc(void * arg)
{
int i;
for(i=0; i<5000000; i++)
num+=1;
return NULL;
}
void * thread_des(void * arg)
{
int i;
for(i=0; i<5000000; i++)
num-=1;
return NULL;
}

두 쓰레드가 하나의 전역변수 num에 여러 번 접근하기 때문에, 오류 발생