반응형
공유자원(파일)에 대해서 pthread의 lock에 대해 알아보던 중 pthread_mutex_lock 외에도 pthread_mutex_trylock, pthread_mutex_timedlock이 있다는걸 알게되었다.
추가적으로 dead lock 가능성을 피하기 위해 잠시 dead lock에 대해 복습해 보면 dead lock 두가지 상황에서 발생할 수 있다.
1) A thread에서 mutex lock변수 a를 이용해서 lock을 진행한 상태에서 다시 a를 lock 하려고 할때 발생.(보통 재귀적으로 구현 된 함수에서 lock을 거는 경우 발생함)
2) A thread에서 mutex lock변수 a를 lock하고 B thread에서 mutex lock변수 b를 lock을 한 상태에서 A thread에서 b를 이용해서 lock을 시도하는 경우 발생.
dead lock이 안생기도록 로직을 짜는게 최선이지만 현실적으로 어느 상황에서 dead lock이 발생할지 예상하기 힘들다.
pthread mutex lock함수를 보면 다음과 같다
- int pthread_mutex_lock(pthread_mutex_t *mutex);
- int pthread_mutex_trylock(pthread_mutex_t *mutex);
- int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);
각각의 함수마다 조금씩 기능이 다른데 구현 하려는 프로그램에 맞게 적절히 사용하면 된다.
간단한게 특성을 보면 pthread_mutex_lock의 경우 해당 lock이 사용중인 경우 unlock될 때 까지 lock을 구하는 쓰레드는 블락된다.(dead lock의 주된 원인)
pthread_mutex_trylock은 사용하려는 lock이 사용중이면 EBUSY를 리턴하고 사용가능 할 경우 임계영역에 접근한다.
phtread_mytex_timedlock timespec 구조체에 sec와 nano sec를 설정하면 설정 된 시간안에 lock을 획득하지 못하면 오류를 반환함.
예제 코드
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <time.h> pthread_mutex_t mutex_lock; void* test_mutex_lock(void *data){ pthread_mutex_lock(&mutex_lock); for(int i=0;i<5;i++){ printf("test_mutex_lock :%d\n",i); sleep(1); } pthread_mutex_unlock(&mutex_lock); return NULL; } void* test_mutex_try_lock(void *data){ if(pthread_mutex_trylock(&mutex_lock)==0){//NOT EBUSY for(int i=0;i<5;i++){ printf("test_mutex_try_lock :%d\n",i); sleep(1); } pthread_mutex_unlock(&mutex_lock); }else{ printf("test_mutex_try_lock failed!\n"); } return NULL; } void* test_mutex_timed_lock(void *data){ struct timespec ts; ts.tv_sec=1; ts.tv_nsec=0; pthread_mutex_timedlock(&mutex_lock,&ts); for(int i=0;i<5;i++){ printf("test_mutex_timed_lock :%d\n",i); sleep(1); } pthread_mutex_unlock(&mutex_lock); return NULL; } int main(void){ pthread_t pid[3]; int thr_id; int status; pthread_mutex_init(&mutex_lock, NULL); thr_id = pthread_create(&pid[0], NULL, test_mutex_lock, NULL); if (thr_id < 0) { perror("thread create error : "); exit(0); } thr_id = pthread_create(&pid[1], NULL, test_mutex_try_lock, NULL); if (thr_id < 0) { perror("thread create error : "); exit(0); } thr_id = pthread_create(&pid[2], NULL, test_mutex_timed_lock, NULL); if (thr_id < 0) { perror("thread create error : "); exit(0); } pthread_join(pid[0], (void **)&status); pthread_join(pid[1], (void **)&status); pthread_join(pid[2], (void **)&status); return 0; } | cs |
반응형
'리눅스' 카테고리의 다른 글
[glib] 메인루프 (0) | 2018.03.04 |
---|---|
리눅스 signal (0) | 2018.02.17 |
pthread에서 메모리 침범과 pthread_cancel (1) | 2018.01.21 |
정적 라이브러리(static library)와 공유 라이브러리(shared library) (0) | 2018.01.14 |
pthread 사용시 주의할점과 tread detach, join에 관해 (0) | 2017.12.14 |