pthread_mutex_* 와 pthread_cond_*를 사용한 동기화문제
글쓴이: shiefra / 작성시간: 금, 2004/11/12 - 11:00오후
똑같은 main을 사용하는 두 thread간의 문제인데요.
코드는,
do { . . . . pthread_mutex_lock (&mutex_lock); // A if (!start) pthread_cond_wait (&cond, &mutex_lock); // B start=0; C.S. pthread_mutex_unlock (&mutex_lock); sleep(1); pthread_cond_signal (&cond); }while (...)
시나리오는 이렇습니다.
1. 첫번째 thread가 A를 무사히 통과해서 CS를 실행하는 동안에 두번째 thread가 A에서 block 됩니다. (처음 thread는 cond_wait를 호출하지 않습니다.)
2. CS를 마친 첫번째 thread가 C에서 mutex를 unlock 하고, 두번째 thread는 mutex가 풀리면서 다음라인을 실행하다가 cond_wait에서 다시 block됩니다.
3. 이 때 첫번째 thread가 cond_signal을 호출해서 두번째 thread를 깨웁니다.
문제는 sleep(1) 부분인데요,
첫번째 thread가 cond_signal을 하기 전에
두번째 thread가 cond_wait를 했다는 보장이 없는것 같아서
sleep()를 쓴건데, 이 방법 말고 눈에 보이는 지연시간없이
두번째 thread가 cond_wait를 cond_signal 보다 먼저 하게 보장해줄 수 없을까요?
그리고, mutex랑 cond를 저렇게 쓰는게 맞는건지도 잘 모르겠습니다.
sleep(1) 포함해서 원하는대로 동작하는것 같지만 그래도 불안..
Forums:
원하시는 동작이 쓰레드들간에 Critical Section 을 위해서 동
원하시는 동작이 쓰레드들간에 Critical Section 을 위해서 동기화 작업이 필요하신 것이라면 pthread_con_* 를 사용하실 필요가 없습니다. 그런 용도라면 단순히 mutex_lock / unlock 으로 충분합니다.
pthread_con_* 의 사용처는 mutex 와는 좀 다릅니다. condition variable 은 pthread_wait 로 대기하는 쓰레드를 원하는 상황이 오면 깨우기 위해서 사용됩니다.
mutex 는 쓰레드가 각각 동등한 입장에서 동일한 리소스를 한번에 억세스하지 못하도록 하는 것이고, cond. var. 은 한쪽은 이벤트를 만들고 다른 한쪽 (혹은 여러) 쓰레드는 대기하고 있다가 신호가 오면 깨어나도록 하는 것입니다.
이것의 대략적인 용법은 UNP 23 장이 도움이 될 것 같습니다.
pthread
저의 경우 Windows 프로그래밍을 하다가 Linux쪽 프로그래밍을 하다보니
이 문제때문에 골치좀 아팠었습니다.
pthread 이넘... WIN32에 익숙한 프로그래머 입장에서 좀 짜증나죠.
pthread_cond_wait() 이넘의 문제는 wait를 하고 있는 쓰레드가 있다면 깨워지지만 wait를 하고 있는 쓰레드가 없었다면... 아무것도 깨우지 않습니다. -_-;
그리고 WIN32는 쓰레드 핸들, 이벤트 핸들등.. 핸들이라는 이름을 갖는 모든 녀석을 한꺼번에 기다릴 수 있는 WaitForMultipleObjects() 라는 아주 멋진 API도 사용할 수 있지만 pthread는 여러개의 condition 개체를 한꺼번에 기다릴 수 있는 방법도 없고 개체의 종류(thread, condition)에 따라 다른 wait 펑션을 이용해야 합니다.
어째튼.. 해결법은...
이겁니다. 아래를 보시면 아시겠지만...
pthread_cond_signal()을 그냥 주시지 말고 state라는 변수를 하나 더 이용해야 합니다.
기다릴때는 state가 FALSE 일때 pthread_cond_wait()를 해 주시면 됩니다.
참고로 제가 사용하는 wait 펑션을 아래에 첨부하겠습니다.
저의 경우 한개의 소스코드로 Windows와 Linux에서 동시에 컴파일 되도록 개발하기때문에 좀 추상화 시켰습니다.
참고로
* wait_sec은 기다릴 시간
* manual_reset는 자동/수동 reset 기능은 갖습니다.
댓글 달기