http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Thread/Beginning/Mutex
2 공유 자원에 대한 접근 제어
- global int count = 0
- A 쓰레드가 count값 0을 읽는다.
- B 쓰레드가 count값 0을 읽는다.
- A 쓰레드가 카운팅 연산을 하기 전에 B쓰레드가 접근해 버린 상황이다.
- A 쓰레드가 count+1 연산을 하고 값을 쓴다. count = 1
- B 쓰레드가 count+1 연산을 하고 값을 쓴다. count = 1
3 동기화 달성의 방법
- count 값을 읽어와서
- 카운팅 연산을 하고
- 연산 결과를 저장하는
- global int count = 0;
- A 쓰레드가 임계 영역에 진입
- B 쓰레드도 임계 영역 진입을 시도하지만, A 쓰레드가 진입해 있으므로 임계 영역 밖에서 대기한다.
- A 쓰레드가 count 값을 읽고
- 카운팅 연산을 해서
- 값을 저장한다. count = 1
- A 쓰레드가 임계 영역에서 빠져나온다.
- 비로서 B 쓰레드가 임계 영역에 진입해서
- count 값 1을 읽어서 카운팅 연산을 하고 저장한다. count = 2
4 Mutex
global int v = 1; lock() { while(1) { if (v==1) break; } v = 0; return 1; } unlock() { v = 1; break; }
- Atomicity - mutex 잠금(lock)는 최소단위 연적(atomic operation) 으로 작동한다. 이말의 뜻은 하나의 쓰레드가 mutex 를 이용해서 잠금을 시도하는 도중에 다른 쓰레드가 mutex 잠금을 할수없도록 해준다는 뜻이다. 한번에 하나의 mutex 잠금을 하도록 보증해준다.
- Singularity - 만약 스레드가 mutex 잠금을 했다면, 잠금을 한 쓰레드(:12)가 mutex 잠금을 해제 하기 전까지 다른 어떠한 쓰레드도 mutex 잠금을 할수 없도록 보증해준다.
- Non-Busy Wait - 바쁜대기 상태에 놓이지 않는다는 뜻으로, 하나의 쓰레드가 mutex 잠금을 시도하는데 이미 다른 쓰레드가 mutex 잠금을 사용하고 있다면 이쓰레드는 다른 쓰레드가 락을 해제하기전까지 해당 지점에 머물러 있으며 이동안은 어떠한 CPU 자원도 소비하지 않는다 (이를테면 sleep).
5 뮤텍스 만들기
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutex_attr *attr);
- mutex : 뮤텍스 객체
- attr : 뮤텍스 생성 특성, NULL 이면 기본 특성을 가진다.
6 뮤텍스 잠금, 잠금해제, 제거
int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_destory(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);다음은 쓰레드간 공유되는 자원을 위해서 잠금을 어떻게 사용하는지를 보여주는 간단한 예제다.
#include <stdio.h> #include <unistd.h> #include <pthread.h> int ncount; // 쓰레드간 공유되는 자원 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화 void* do_loop(void *data) { int i; for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); // 잠금을 생성한다. printf("loop1 : %d\n", ncount); ncount ++; if(i == 10) return; pthread_mutex_unlock(&mutex); // 잠금을 해제한다. sleep(1); } } void* do_loop2(void *data) { int i; // 잠금을 얻으려고 하지만 do_loop 에서 이미 잠금을 // 얻었음으로 잠금이 해제될때까지 기다린다. for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); // 잠금을 생성한다. printf("loop2 : %d\n", ncount); ncount ++; pthread_mutex_unlock(&mutex); // 잠금을 해제한다. sleep(2); } } int main() { int thr_id; pthread_t p_thread[2]; int status; int a = 1; ncount = 0; thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a); sleep(1); 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); printf("code = %d", status); printf("programing is end"); return 0; }위의 코드를 우선 mutex 잠금을 하지 않은체 컴파일후 실행해보자. 간단하게 pthread_mutext_lock 와 pthread_mutex_unlock 부만 주석처리하면 된다. 그러면 do_loop2 와 do_loop 가 일정한 간격을 두고 ncount 자원에 접근하는 것을 볼수 있을것이다. 그러나 우리는 do_loop 가 ncount 자원을 접근하고 있는동안 다른 쓰레드가 접근하지 않기를 원할때가 있을것이다. 이럴때 뮤텍스 잠금을 사용하면 된다.
'리눅스 서버에 대해서 > 솔라리스(UNIX) 관련' 카테고리의 다른 글
어플리케이션 개발자를 위한 솔라리스와 리눅스 차이점 (0) | 2013.01.10 |
---|---|
솔라리스에서 파일 첨부 (0) | 2013.01.09 |
유닉스 Thread 시스템프로그래밍 (0) | 2013.01.09 |
솔라리스 기본 설정 (텍스트) (0) | 2013.01.04 |
솔라리스 pkg 설치. (0) | 2013.01.04 |