pthread 에서 lock 과 unlock 에 대해서 질문입니다.
글쓴이: sugarlessgirl / 작성시간: 일, 2003/10/12 - 1:42오후
안녕하세요..
unix network programming vol.2 를 보다가 잘 이해가 안가는 것이 있어서 질문 드립니다.
void * produce(void *arg) { ... Pthread_mutex_lock(&nready.mutex); if (nready.nready == 0) Pthread_cond_signal(&nready.cond); nready.nready++; Pthread_mutex_unlock(&nready.mutex); ... }
void * consume(void *arg) { int i; for (i = 0; i < nitems; i++) { Pthread_mutex_lock(&nready.mutex); while (nready.nready == 0) Pthread_cond_wait(&nready.cond, &nready.mutex); nready.nready--; Pthread_mutex_unlock(&nready.mutex); if (buff[i] != i) printf("buff[%d] = %d\n", i, buff[i]); } return(NULL); }
소스는 이런데요..
pthread_cond_wait 가 실행되면, 자신이 lock 하고 있는 mutex 를 unlock 시키고 블락되고, 리턴될때 unlock 한 Mutex 를 다시 Lock 한다고 알고 있습니다.
그럼 produce 함수에서, Pthread_cond_signal 로 wait 되어있는 thread 를
깨울때,
produce 함수에서 Pthread_mutex_unlock 까지 처리한 뒤에,
wait 되어있는 쓰레드를 깨웁니까?
아니면,
Pthread_cond_signal 이 실행되는 순간, 자신을 block 시키고,
wait 하고 있는 thread 를 깨우고, 그 쓰레드가 mutex 를 unlock 하면,
다시 깨어나 작업을 진행하게 되는건가요?
아니면, 언제 자신을 block 하고, wait 되어 있는 thread 를 깨우는지
그 시점을 전혀 예측 할 수 없는 건가요?
뒷 페이지(170) 에 보면 Avoiding Lock Conflicts 부분에서,
Quote:
In a worst-case scenario, we could imagine the system immediately scheduling the thread that is signaled; that thread runs and then immediately stops, because it cannot acquire the mutex.
이런 말이 나오는데요..
제가 위에서 질문한 예측 불가능한 상황을 말하는 것인가요?
이 부분 확실히 이해하고 넘어가야 될 것 같은데..
뭐가 어떻게 돌아가는 건지 모르겠습니다.
아시는 분 도움 부탁드려요..
감사합니다.
Forums:
대기하는 쓰레드를 A, 시그널을 발생하는 쓰레드를 B라고 보죠.다음과
대기하는 쓰레드를 A, 시그널을 발생하는 쓰레드를 B라고 보죠.
다음과 같은 순서로 실행됩니다.
mutex_lock(A) -> cond_wait call(A) -> mutex_lock(B) -> cond_signal(B) -> mutex_unlock(B) -> cond_wait return(A) -> mutex_unlock(A)
man 페이지에 있는 내용은 cond_signal(B) 이후에 mutex_unlock(B)하기
전까지 cond_wait return(A)를 못한다는 의미입니다.
다시말해, 시그널을 받아서 깨어났지만, B가 mutex_lock을 가지고있기 때문에
다시 대기 상태로 들어간다는 의미이지요. (물론 깨어났다가 대기한다고
표현되어 있지만, 그리 비효율적인 동작은 아닙니다.)
윗분이 잘 설명해주셨네요.
일반적으로 이렇게 하는 이유는 synchronization문제때문입니다. wait 상태에 들어간 녀석이 signal을 받고 작동할때는 대부분 produce와 같은 일감을 주는 녀석이 일감을 주고 작동하게 되는데, 이때 시스템의 미묘한 시간차이로 인해서 이 함수내에서의 모든 오퍼레이션이 작동하고 리턴하기전에 consume에 있는 wait 된 녀석이 더 빨리 깨어나면 안되기 때문에 mutex를 이용하는 것이죠.
따라서 위와 같이 mutex를 걸지 않고 사용할경우에는 timing error에 빠질 수 있는 경우도 있습니다. 위의 ready 를 ++ 시키는 도중에 아랫쪽 -- 가 실행되는 재수없는 경우를 볼수도 있기 때문입니다. 이런 문제는 시그널처리에서도 똑같이 발생가능합니다. 흠... 시그널쪽이 조금더 복잡하죠. atomic하다라고 해줄 수 있도록 이런 프로그램은 신경써주는게 가장 중요하다고 생각됩니다.
PS) 윗분이 텍스트 그림까지 그리셔서 신경을 많이 써서 답변해주셨네요. 그리고 고양이 이쁘군요. 저도 예전에 페르샨하나 키웠는데... 지금은... -.ㅜ
========================================
* The truth will set you free.
댓글 달기