바람직한 Producer-Consumer 모델 Programming

가마수트라에 멀티스레딩 관련해서 좋은 글이 있어서 부분적으로 옮겨봤습니다. 원문은 여기 입니다. 새로운 개념은 아니지만 기본 개념을 잘 설명하고 있습니다.

이벤트는 다른 스레드에서 신호를 받는 수단입니다. 한 스레드에서는 다른 스레드에서 신호를 받기 전까지 대기할 수 있습니다. 아래 예제에서는 두 스레드간에 어떻게 이벤트를 사용하는지 보여줍니다. 왼쪽의 스레드는 데이터를 생산(Producer)하고 오른쪽의 스레드에서는 데이터를 소비(Consumer)합니다.
 


 생산자 스레드에서는 데이터를 생산하여 공용 작업 영역에 넣습니다. 이 예제에서는 소비자 스레드는 이벤트가 발생할 때까지 대기합니다(sleep).


생산자 스레드에서 데이터를 다 넣으면, 이벤트를 발생시킵니다.

이 신호가 자고 있는 스레드를 깨웁니다.
 


소비자 스레드가 깨어나면 공용 작업 영역에서 데이터를 꺼내어 작업을 시작합니다. 이 시점에서 생산자 스레드에서는 공용 작업 영역을 건드리지 않는 다는 보장이 필요합니다.
아래에 코드가 있습니다.
이 코드에서는 스레드를 생성하고 생성된 스레드에서는 이벤트가 발생될 때까지 대기합니다. 메인 스레드에서는 데이터를 전역버퍼에 넣고 이벤트를 발생시킵니다. 이벤트가 발생되면 자고 있던 스레드가 깨어나서 전역 버퍼에 있는 데이터를 프린트합니다.

 생산자-소비자 모델을 위와 같이 구현하지 않고 소비자 스레드에서 지속적으로 데이터가 들어오는 것을 체크하는 식으로 구현하게 되면 이른바 바쁜대기(Busy Wait) 상태가 되어 성능에 좋지 않은 영향을 줍니다. 실제 데이터를 처리하는데 소비하는 시간보다는 데이터가 들어있는지 체크하는데 걸리는 시간이 더 많이 걸리는 것입니다.

 ACE에서는 ACE_Message_Queue에서 위와 같은 생산자-소비자 모델을 구현하고 있습니다. 데이터를 꺼낼 때 timeout값을 줄 수도 있는데, 이 값은 데이터가 들어올 때까지 무한정 대기할 것인지 혹은 몇ms동안만 대기하다가 리턴 할 것인지를 결정합니다. 물론 가장 이상적인 모델은 데이터가 들어올 때까지 계속 대기하는 것입니다. ACE_Message_Queue에서는 queue를 스레드 세이프하게 만들어서 생산자 혹은 소비자 스레드가 몇 개가 되더라도 상관없이 동작하도록 할 수 도 있습니다. 이것은 템플릿 인자로 지정이 가능합니다.

핑백

  • flexible gameserver : lock-free 회의론 2009-10-02 05:54:09 #

    ... 나 context switching을 줄임으로서 얻는 성능의 향상이 더 컸습니다. Proactor 패턴 Half-Sync/Half-Async 패턴 바람직한 Producer-Consumer 모델 lock-free 알고리즘을 이해하고 구현하는데 시간을 들이는 것보다는 기존의 concurrent 패턴을 잘 이해하고, 그안에서 성능을 향 ... more

덧글

댓글 입력 영역