인프런 커뮤니티 질문&답변

snu님의 프로필 이미지
snu

작성한 질문수

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

Condition Variable 질문입니다.

작성

·

129

0

//Producer

while(true)

{

{

unique_lock<mutex> lock(m);

q.push(100);

}

cv.notify_one();

}

 

//Consumer

while(true)

{

unique_lock<mutex> lock(m);

cv.wait(lock,[](){return q.empty()==false;});

{

int32 data = q.front();

q.pop();

cout<<data<<endl;

}

}

 

1. Producer에서 cv.notify_one(); 을 한 뒤 Consumer의 cv.wait가 깨어나기 전에 Producer가 unique_lock<mutex> lock(m); 을 걸면 pop을 하지 못하고 queue에 데이터가 연속으로 쌓이는 경우가 있나요?

 

2. 디버깅을 찍어보니 cv.wait가 처음 수행되었을 때는 cv.notify_one() 없이도 그냥 깨어나던데 cv.wait는 notify를 해줬을 경우만 깨어나지 않나요?

ex) 스레드 Producer, Consumer을 모두 실행 직후 최초 q.push 이후 notify_one 없이 wait가 깨어나 data를 cout 함.

 

3. notify_one 해줬을 때 cv.wait의 [](){return q.empty()==false;} 조건이 충족되지 않았을 때 대기를 하는데(queue에 아무것도 없는 상태)

이때, queue 에 push를 해주면 별도의 반복 notify_one 작업 없이 바로 깨어나나요? 

디버깅을 해보니 notify_one을 걸고 조건 실패하여 대기중일때 queue에 push를 해주니 꺠어나는것 같았습니다.

notify_one은 1회성으로 바로 리턴하고 끝인줄 알았는데 Count가 하나 증가하여 queue에 data가 쌓일때까지 대기하는? 개념인지 궁금합니다.

답변 1

1

Rookiss님의 프로필 이미지
Rookiss
지식공유자

1. 네 그렇습니다.
2. 꼭 그렇진 않고, 구조상 깨어나서 허탕칠 가능성도 있습니다. 이를 전문적으로 spurious wakeup이라고 합니다.

https://en.wikipedia.org/wiki/Spurious_wakeup

3. 그 정도로 스마트하게 동작하진 않구요. 깨어났을 때 허탕치고 다시 잠들면, 다시 깨워줘야 합니다.
물론 2번에서처럼 중간 중간에 자연스럽게(?) 잠에서 깨는 경우도 있으니
너무 완벽하게 구조를 이해하려 할 필요는 없습니다.

snu님의 프로필 이미지
snu

작성한 질문수

질문하기