티스토리 뷰
multi-thread programming for thread-safe.
multi-thread환경에서의 개발을 하게 될 경우 thread-safe에 대한 고민은 하지 않을 수 가 없다.
이유인 즉 슨 다수의 thread가 하나의 global variable이나 static variable에 값에 대한 접근 및 변경 떄문인데 이를 해결하기 위
해 보통 mutex-lock 을 사용하여 programming을 하게 된다. 이러한 경우 2개의 thread가 존재 할 경우 먼저 실행된 thread가
자원을 선점하게 되고 두번쨰 thread는 unlock시점까지 대기상태가 된다.
thread-safe의 예
#include <stdio.h> #include <unistd.h> #include <pthread.h> int ncount; // 쓰레드간 공유되는 자원 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화 // 쓰레드 함 수 1 void* do_loop(void *data) { int i; pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop1 : %d\n", ncount); ncount ++; sleep(1); } pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } // 쓰레드 함수 2 void* do_loop2(void *data) { int i; // 잠금을 얻으려고 하지만 do_loop 에서 이미 잠금을 // 얻었음으로 잠금이 해제될때까지 기다린다. pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop2 : %d\n", ncount); ncount ++; sleep(1); } pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } int main() { int thr_id; pthread_t p_thread[3]; int status; int a = 1; ncount = 0; thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a); sleep(3); thr_id = pthread_create(&p_thread[1], NULL, do_loop2, (void *)&a); pthread_join(p_thread[0], (void *) &status); pthread_join(p_thread[1], (void *) &status); pthread_join(p_thread[2], (void *) &status); status = pthread_mutex_destroy(&mutex); return 0; }
결과값
loop1 : 0
loop1 : 1
loop1 : 2
loop1 : 3
loop1 : 4
loop1 : 5
loop1 : 6
loop1 : 7
loop1 : 8
loop1 : 9
loop2 : 10
loop2 : 11
loop2 : 12
loop2 : 13
loop2 : 14
loop2 : 15
loop2 : 16
loop2 : 17
loop2 : 18
loop2 : 19
위 프로그램을 실행하면 총 두번의 mutex lock이 발생하게 된다.
futex(0x7f98ef6d09d0, FUTEX_WAIT, 25674, NULL) = 0
futex(0x7f98eeecf9d0, FUTEX_WAIT, 25683, NULL) = 0
* futex란 spin lock 이라 불리며 kernel space가닌 user space의 메모리에 존재함으로 성능상의 이득을 볼 수 있다. ( linux kernel 2.6이상 부터 지원. )
thread-safe 하지 않을 경우의 예
#include <stdio.h> #include <unistd.h> #include <pthread.h> int ncount; // 쓰레드간 공유되는 자원 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화 // 쓰레드 함 수 1 void* do_loop(void *data) { int i; // pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop1 : %d\n", ncount); ncount ++; sleep(1); } // pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } // 쓰레드 함 수 2 void* do_loop2(void *data) { int i; // pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop2 : %d\n", ncount); ncount ++; sleep(1); } // pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } int main() { int thr_id; pthread_t p_thread[3]; int status; int a = 1; ncount = 0; thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a); thr_id = pthread_create(&p_thread[1], NULL, do_loop2, (void *)&a); pthread_join(p_thread[0], (void *) &status); pthread_join(p_thread[1], (void *) &status); status = pthread_mutex_destroy(&mutex); return 0; }
결과값
loop2 : 0
loop1 : 1
loop2 : 2
loop1 : 2
loop2 : 4
loop1 : 4
loop2 : 6
loop1 : 6
loop2 : 8
loop1 : 8
loop2 : 10
loop1 : 10
loop2 : 12
loop1 : 12
loop1 : 14
loop2 : 14
loop1 : 16
loop2 : 17
loop1 : 18
loop2 : 18
* thread-safe의 경우 동기화된 값을 출력하지만 thread-safe하지 않은경우 동기화 되지 않은 결과 값이 출력됨. ( single core CPU 환경에선 동시에 돌일이 없기 떄문에 의미 없음. )
mutex lock을 사용하지 않게되면 thread-safe하지 않은 값을 return 받게 될 수 있기때문에 따라서 multi-thread 환경에서는
global 변수 사용을 지양하고 local 변수의 사용을 권장한다. 그래야 thread-safe에 대한 안정성 보장을 할 수 있기 때문이다.
mutex lock을 사용하여 동기화를 구현 할 수 있지만 mutex lock은 잘못사용하게 될 경우 독이 될수 있기 때문이다.
( dead lock 등의 위험요소 존재.)
.by rocksea
'Developer' 카테고리의 다른 글
[ORACLE] user 생성 및 권한 부여. (0) | 2014.02.07 |
---|---|
[ORACLE] ORA-01078, LRM-00109 Error. (0) | 2014.02.07 |
[linux] yum daum repository 설정 (0) | 2014.02.04 |
[webmail] roundcube mail server installation guide (0) | 2014.01.28 |
[gdb] c object file debugger (0) | 2014.01.27 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 조동사
- 베트남
- redis
- NGINX
- AWS
- 스페인 여행
- 해외여행
- hdfs
- maven
- mongoDB
- 비지니스 영어
- Business English
- 대명사 구문
- Python Django
- Python
- hadoop
- 비교구문
- ubuntu
- nodejs
- 여행
- 가정법
- JBOSS
- PostgreSQL
- 영작
- memcached
- 다낭
- it
- k8s
- 영문법
- 도덕경
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함