170 likes | 336 Views
Thread Programming. 2005. 4. 18( 월 ) 한 민 규 hufs96mk@hufs.ac.kr. Thread Stack. Thread Stack. Thread Stack. Thread Stack. Global Variables. Heap. Global Variables. Heap. Thread?. 경량화 된 프로세스 프로세스와 마찬가지로 동시실행이 가능함 프로세스의 단점을 극복하기 위해 등장 프로세스와의 차이점 스텍을 제외한 나머지 메모리 공간을 공유
E N D
Thread Programming 2005. 4. 18(월) 한 민 규 hufs96mk@hufs.ac.kr
Thread Stack Thread Stack Thread Stack Thread Stack Global Variables Heap Global Variables Heap Thread? • 경량화 된 프로세스 • 프로세스와 마찬가지로 동시실행이 가능함 • 프로세스의 단점을 극복하기 위해 등장 • 프로세스와의 차이점 • 스텍을 제외한 나머지 메모리 공간을 공유 • 보다 간단한 컨텍스트 스위칭(context switching) • 일부메모리를 공유하므로 스레드간 통신이 편리 Process Thread 1 Thread Thread 1 Thread 1
Thread? (con’t) • Process vs Thread
#include <pthread.h> int pthread_create (pthead_t * thread, pthread_attr-t * attr, void * (* start_routine) (void *), void * arg ); 성공 시 0, 실패 시 이외의 값 리턴 Thread Creation • Thread Create Function • thread : 생성된 쓰레드의 ID를 저장할 변수의 포인터를 인자로전달 • Attr : 생성하고자 하는 쓰레드의 특성(attribute)을 설정할 때 사용, 일반적으로 Null을 전달 • Start_routine : 리턴타입과 인자가 void*인 함수를 가르키는 포인터 • Arg : 쓰레드에 의해 호출되는 함수에 전달하고자 하는 인자값을넘겨줌
Thread Creation(Con’t) • pthread_create() - example #include <pthread.h> void *thread_function(void *arg); int main(int argc, char **argv){ int state; pthread_t t_id; void *t_return; state = pthread_create(&t_id, NULL, thread_function, NULL); if(state != 0){ puts(“thread create fail"); exit(1); } printf(“created thread ID : %d \n", t_id); sleep(3); puts(“main function exit"); return 0; } void * thread_function(void *arg) { int i; for(i=0; i<3; i++){ sleep(2); puts(“progress thread"); } }
Process 쓰레드 생성 Thread 종료 종료 Thread Creation(Con’t) – example result
#include <pthread.h> int pthread_join(pthead_t * th, void **thread_return); ); 성공 시 0, 실패 시 이외의 값 리턴 Thread Creation(Con’t) • Blocks the calling thread • th : th에 인자로 들어오는 ID의 쓰레드가 종료할 때까지 실행 지연 • thread_return : 쓰레드가 종료 시 반환하는 값에 접근할 수 있는 2차원포인터
Process 쓰레드 생성 Thread JOIN 대기상태 RETURN 종료 종료 Thread Creation(Con’t) • pthread_join() - result
Multi Thread Creation • 임계영역(Critical Section)과 쓰레드에 안전한 함수의 호출 • 임계영역 • 두개 이상의 쓰레드에 의해서 동시에 실행되면 안 되는 영역 • 쓰레드 관점에서 볼 때 함수의 종류 • 쓰레드 불안전한 함수(Thread-unsafe Function) • 단일 쓰레드 모델에서는 사용 가능함 함수이지만 다중 쓰레드 모델에서는 사용할 수 없는 함수(gethostbyname) • 쓰레드 안전한 함수(Thread-safe Function) • 다중 쓰레드 모델에서 사용 가능한 함수(gethostbyname_r)
Multi Thread Creation(Con’t) • Multi Thread Cration & join - example void *thread_summation(void *arg); int sum=0; int sum1[]={1, 5}; int sum2[]={6, 10}; int main(int argc, char **argv){ pthread_t id_t1, id_t2; void *t_return; pthread_create(&id_t1, NULL, thread_summation, (void *)sum1); pthread_create(&id_t2, NULL, thread_summation, (void *)sum2); /* 쓰레드 종료 시까지 main함수의 실행을 지연 */ pthread_join(id_t1, &t_return); pthread_join(id_t2, &t_return); printf("main function exit : sum = %d \n", sum); return 0; } void * thread_summation(void *arg){ int start = ((int*)arg)[0]; int end = ((int*)arg)[1]; for(; start<=end; start++){ sum+=start; } }
Process 쓰레드 생성 Thread 쓰레드 생성 Thread JOIN RETURN 종료 JOIN 종료 종료 Multi Thread Creation(Con’t) • Result
Critical Section vs Multi Thread Problem • Basic Operation int i = 10 int j = 20 j+=i
Critical Section vs Multi Thread Problem(Con’t) • Multi Thread Operation int i = 10 . . . . . i+=10
Critical Section vs Multi Thread • 임계영역 • 두개 이상의 쓰레드에 의해서 공유되는 메모리 공간에 접근하는 코드영역 • 쓰레드의 동기화 • 공유된 메모리에 둘 이상의 쓰레드가 동시 접근하는 것을 막는 방법 • 둘 이상의 쓰레드 실행 순서를 컨트롤하는 방법 • 대표적인 동기화 기법 • 뮤텍스
Mutex • 뮤텍스 • Mutual Exclusion의 줄임말로 쓰레드들의 동시접근을 허용하지 않겠다는 의미 • Pthread_mutex_t 타입변수를 가르켜 흔히 뮤텍스라고 함 • 뮤텍스의 기본원리 • 임계영역에 들어갈 때 뮤텍스를 잠그고 들어감 • 임계영역을 빠져 나올 때 뮤텍스를 풀고 나옴 • 뮤텍스 조작함수 • 초기화 : pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) • 잠금 : pthread_mutex_lock (pthread_mutex_t *mutex) • 잠금 해제 : pthread_mutex_unlock (pthread_mutex_t *mutex) • 소멸 : pthread_mutex_destroy (pthread_mutex_t *mutex)
Thread B Thread A 임계영역 임계영역 Thread B 진입 Thread B Thread A 임계영역 Thread A 진입상태 Mutex(Con’t) • Mutex Synch 2.Thread B 진입 pthread_mutex_lock 함수 호출 후 임계영역에 진입 [3] [1] Pthread_mutux_lock 함수 호출 후 대기상태 1. Pthread_mutex_unlock 함수 호출 후 임계 영역 탈출 [2]
Mutex(Con’t) • Example void *thread_increment(void *arg); char thread1[] = "A Thread"; char thread2[] = "B Thread"; pthread_mutex_t mutx; int number = 0; int main(int argc, char **argv){ pthread_t t1, t2; void *thread_result; int state; state = pthread_mutex_init(&mutx, NULL); if(state){ puts(“Mutext Init Fail"); exit(1); } pthread_create(&t1, NULL, thread_increment, &thread1); pthread_create(&t2, NULL, thread_increment, &thread2); pthread_join(t1, &thread_result); pthread_join(t2, &thread_result); printf(“finalnumber : %d \n", number); pthread_mutex_destroy(&mutx); return 0; } void *thread_increment(void * arg) { int i; for(i=0; i<5; i++){ pthread_mutex_lock (&mutx); sleep(1); number++; printf (“exec: %s, number : %d \n", (char*)arg, number); pthread_mutex_unlock (&mutx); } }