컨디션을 통한 스레드 동기화 예제

동시성을 다룰 때에는 특정한 자원을 동시에 액세스하지 못하도록 관리하거나 여러 작업들이 시작되는 시점을 맞추는 동기화 수단이 필요할 수 있다. Lock은 특정 코드 영역을 동시에 여러 스레드가 실행하지 못하도록 보호할 때 사용하며, 이벤트는 여러 스레드들이 특정 이벤트가 발생할 때까지 기다리다가 동시에 시작될 수 있도록 한다. 컨디션(Condition)은 락과 이벤트가 결합되어 있는 동기화 수단이다.

컨디션은 락을 내재하고 있는 이벤트라 할 수 있다. 락과 마찬가지로 acquire() ~ release() 구간이 있어 한 번에 하나의 스레드/프로세스가 실행되는 영역을 만들 수 있는데, 그 사이에 wait()를 통해서 이벤트를 기다릴 수 있다. 이때 한 스레드가 락을 잠근 상태에서 wait()를 호출하여 이벤트를 기다리게 되면, 같은 컨디션 객체를 점유하고자 하는 스레드가 다시 락을 얻어서 크리티컬 영역에 진입할 수 있다. 이와 같은 방식으로 여러 스레드가 크리티컬 영역에서 이벤트를 기다리는 상태가 될 때, 누군가가 해당 컨디션 이벤트를 set()하게 되면 대기 중인 모든 스레드가 깨어나게 된다. 하지만 이들은 모두 같은 크리티컬 영역에서 대기 중이었기 때문에 일반 이벤트와 달리 한꺼번에 동시에 시작하지 않고, 한 번에 하나씩 크리티컬 영역의 코드를 실행한다. 깨어난 스레드가 락을 릴리즈하는 시점에 wait()를 끝낸 다른 스레드가 실행되는 식으로 순차적으로 크리티컬 구간을 지나게 된다.

컨디션을 통한 스레드 동기화 예제 더보기

Barrier를 사용한 동기화

Barrier는 동시성 프로그래밍에서 사용되는 동기화 수단 중 하나로 여러 스레드를 특정한 시점까지 기다린 후 한꺼번에 재개하는 방법이다. 비슷한  방식의 동기화 프리미티브로 이벤트(Event)가 있는데, 이벤트는 재개 시점을 판단하는 제 3의 스레드가 재개를 위한 시그널을 set해주어야 한다. 배리어는 그와 달리 미리 정해진 개수만큼의 스레드가 모이면 자동으로 해제된다.

따라서 배리어는 여러 워커 스레드로 데이터를 분산시켜 병렬로 처리하고 최종적인 작업 완료 이전에 모든 워커 스레드가 작업을 완료했는지를 기다리는 용도로 사용할 수 있다.

Barrier를 사용한 동기화 더보기