bfiber_0500
Boost.Fiber Synchronization Barriers
Synchronization Barriers
장벽(barrier)은 랑데뷰(rendezvous)라고도 알려진 개념으로, 여러 실행 컨텍스트(파이버) 간의 동기화 지점입니다.
장벽은 특정 수의 파이버(n)에 대해 구성되며, 파이버가 장벽에 도달하면 모든 n 파이버가 도착할 때까지 기다려야 합니다.
n 번째 파이버가 장벽에 도달하면 대기 중인 모든 파이버가 진행될 수 있으며 장벽이 재설정됩니다.
장벽이 자동으로 재설정(reset)된다는 사실은 중요합니다.
몇 개의 파이버를 실행하고 그 중 첫 번째 파이버가 완료될 때까지만 기다리려는 경우를 생각해 보십시오.
barrier(2)를 동기화 메커니즘으로 사용하여, 각각의 새 Fiber가 barrier::wait() 메서드를 호출하도록 한 다음,
시작 파이버에서 wait()를 호출하여 첫 번째 다른 파이버가 완료될 때까지 기다리려는 유혹을 받을 수 있습니다.
그러면 실제로 시작 파이버의 차단이 해제됩니다.
불행한 부분은 남은 파이버를 계속 차단한다는 것입니다.
다음 시나리오를 고려해보세요.
1. 파이버 "main"은 파이버 A, B, C 및 D를 시작한 다음 barrier::wait()를 호출합니다.
2. 파이버 C가 먼저 완료되고 마찬가지로 barrier::wait()를 호출합니다.
3. 원하는 대로 파이버 "main"이 차단 해제됩니다.
4. 파이버 B는 barrier::wait()를 호출합니다. 파이버 B가 차단되었습니다!
5. 파이버 A는 barrier::wait()를 호출합니다. 파이버 A와 B는 차단되지 않습니다.
6. Fiber D는 barrier::wait()를 호출합니다. 파이버 D는 무기한 차단됩니다.
• Note:
참여하는 파이버 중 하나에 장벽의 수명(lifespan)을 묶는 것은 현명하지 않습니다.
개념적으로 모든 대기 파이버는 "동시에(simultaneously)" 깨어나지만 파이버의 특성으로 인해
실제로는 불확실한(indeterminate) 순서로 하나씩 깨어납니다.[1]
나머지 대기 파이버는 wait()에서 계속 차단되며, 반환하기 전에 장벽 객체의 데이터 멤버에 액세스해야 합니다.
[1] 현재 구현에서는 FIFO 순서로 파이버를 깨웁니다. 즉, wait()를 먼저 호출한 파이버가 먼저 깨어나는 식입니다.
그러나 다양한 파이버가 wait() 호출에 도달하는 순서에 의존하는 것은 위험(perilous)합니다.
📦 Class barrier
장벽(barrier) 인스턴스는 복사하거나 이동할 수 없습니다.