[C++] Condition Variable(조건 변수)

kimyb·2023년 1월 10일

Condition Variable(조건 변수)는 멀티스레딩 환경에서 스레드 간 동기화를 위한 중요한 기법 중 하나로,

기본적으로 주로 스레드가 어떤 조건이 충족될 때까지 기다리고, 다른 스레드가 그 조건을 충족시킬 때까지 대기하는 데 사용된다.

(헤더는 <condition_variable> )
(처음 Condition Variable를 공부했을때 콜백함수와 비슷한줄 알았는데, 사용목적과 메커니즘이 다르다.)

1. 기본적인 패턴은 mutex와 함께 사용.

  // 조건 변수 및 뮤텍스 생성
  std::condition_variable cv;  // 조건 변수
  std::mutex mtx;              // 뮤텍스 (스레드 간 공유 데이터 보호)
  bool if_tf = false;
void other_thread() 
{
		{
		// 데이터 변경 및 조건 검사
		// 스레드는 데이터를 변경한 후, 조건이 충족되었음을 알릴때, 뮤텍스는 잠금 상태이어야 함.
		 	std::unique_lock<std::mutex> lock(mtx); // 뮤텍스 잠금
         	if_tf = true;
		}
		cv.notify_all(); // 또는 cv.notify_one()
}


//  조건이 충족될 때까지 대기.
// 또 다른 스레드
{
		cv.wait(lock, [] { return  if_tf; });
		 // 뮤텍스는 여기에서 자동으로 잠금 해제.
}
// 다음 실행


2. Condition Variable 주ㅡ요 멤버 함수.

  1. wait(std::unique_lock<std::mutex>& lock, Predicate pred)

    • 현재 스레드를 뮤텍스 lock을 락하고 대기 상태로 만듦.
    • Predicate는 조건을 검사하는 함수나 람다 표현식으로, 조건이 true일 때까지 스레드가 대기.
    • 조건이 만족되지 않으면 스레드는 블록.
    • 다른 스레드가 notify_one() 또는 notify_all()을 호출하여 신호를 보내면 대기 중인 스레드 중 하나가 깨어나고, 다시 조건을 확인.
  2. void notify_one()

    • 이 함수는 대기 중인 스레드 중 하나를 깨움.
    • 호출 시, 대기 중인 스레드 중 하나가 무작위로 선택되어 깨어나고, 스레드는 뮤텍스를 얻으려 함.
  3. void notify_all()

    • 이 함수는 대기 중인 모든 스레드를 깨움.
    • 호출 시, 모든 대기 중인 스레드가 깨어나려고 시도하며, 스레드들은 뮤텍스를 얻으려 함.
      (이때 경쟁이 발생되면, 성능 저하까지 될 수 있음.)
  4. wait_for(std::unique_lock<std::mutex>& lock, const std::chrono::duration<Rep, Period>& rel_time, Predicate pred)

    • 일정 시간 동안 스레드를 대기 상태로 만듦, time out 또는 true가 될 때까지 스레드를 대기.
    • 시간이 경과하면 스레드가 깨어나고, 조건을 확인.
profile
공부했던것을 정리.

0개의 댓글