스레드의 시작 시점을 동기화하기
동시성 프로그래밍에서 동기화는 주로 한정된 자원을 두고 여러 스레드가 경쟁하지 않도록 락이나 세마포어를 사용해서 특정한 자원을 액세스하는 시점에서는 여러 스레드가 순차적으로 실행하도록 하는 것에 초점을 맞추고 있다. 하지만 이 외에도 각각의 스레드가 각자가 담당한 작업을 처리하기 위해 준비를 마치고, 다른 스레드의 준비를 기다렸다가 동시에 시작하도록 하는 기법도 필요하다. 이렇게 여러 스레드를 특정한 지점에서 기다리게 한 후 한 번에 깨워서 동시에 시작하게 하는 용도로 사용되는 동기화 프리미티브로는 이벤트와 배리어가 있다.
이런 기법이 가장 흔히 사용되는 경우로는 소켓 서버와 클라이언트를 하나의 스크립트에서 구현해서 스레드로 돌게 할 때이다. 서버의 소켓이 준비되기 전에 클라이언트들이 서버에 connect 될 수 없기 때문이다.
이벤트는 가장 단순한 동기화 프리미티브 중 하나로, 동시에 시작해야 하는 여러 스레드들이 “출발선”에서 이벤트 객체의 .wait()
메소드를 호출하고 대기상태에 들어가도록 한다. 그리고 어느 한 스레드에서 해당 이벤트 객체의 .set()
을 호출하면 해당 이벤트를 대기 중인 모든 스레드에서 wait()
메소드가 리턴되면서 각 스레드가 동시에 시작될 수 있다.
배리어도 비슷하게 여러 스레드를 기다리게하다 한 번에 깨우는 장치인데, 마치 정원이 다 차면 바로 출발하는 버스처럼 작동한다. 즉 이벤트를 기다리는 스레드들은 누군가가 깨워줘야 하는 것에 비해, 배리어 정해진 개수만큼의 스레드가 대기하게 되면 자동으로 해제되면서 동시에 깨어나게 된다.
더 보기 »스레드의 시작 시점을 동기화하기