'Pattern'에 해당되는 글 1건

  1. 2008.08.25 [pattern] Leader/Follower
2008. 8. 25. 19:59

[pattern] Leader/Follower

POSA 2에 나오는 패턴이다.

자세한 내용은 책을 보던가, EvaCast 강좌를 보면 내용을 볼수가 있다.

기존의 Thread Pooling이 Master Thread를 두고 Master Thread가 필요할때 마다 Pool에서 하나씩 꺼내서 사용시키는거라고 하는데, 사실 Thread Pool 이라는 것은 사용해 본적도 없고, 사용할 일도 없어서, 기존의 방법이라는게 어떻게 구현되는건지는 잘 모르겠다.

Leader/Follower 패턴을 대략적으로 살펴보면, Thread Poolling의 한 방법으로 Thread들이 생성이 되면, 그 Thread들 중 하나가 Leader가 되고, 남은 Thread들 중 하나가 Follower가 된다. 나머지 Thread들은 대기 상태.
request가 들어오면 Leader는 그 request들을 처리하러 가고, Follower에게 Leader의 자리를 넘긴다, Follower는 Leader가 되면서, 남은 Thread들중 하나에게 Follower의 자리를 넘겨 주고, 대기하는 과정을 반복하는 것이다.
실제 구현을 본적이 없어서, Leader가 Follower을 정하는지 아니면 다른 규칙이 있는지는 알수가 없다.

대신 기존에 사용된다던 Master Thread가 없어져서, 혹시 모를 Master Thread의 객사(Exception 또는 Dead Lock등이겠지)하면서 생기는 불상사가 없어져서 좋단다.

이 패턴이 대표적으로 사용되는 사용되는 곳을 보자면, POSA2에서는 ORB(Object Request Broker)를 설명하면서 Reactor에 대한 Dispatcher로서 이 패턴을 설명하고 있다. Connector와 Acceptor에서 핸들러를 등록하고 Reactor에서 디스패칭을 하는 구조라고 생각할수 있을것이다.

POSA의 결과물인 ACE에서 찾아 보면, ACE_TP_Reactor라는 곳에서 Event Demultiplexer로 이 패턴을 사용한다고 한다. ACE는 살펴볼 기회가 없어서 이거 쓰면서 실제 구현코드를 대충 살펴만 봤다.

그 다음으로는 Proactor를 설명하면서도 이 패턴에 대한 설명이 나오는데, IOCP가 이 패턴을 사용한다고 한다.

사실 이걸 보기 전까지는 이 패턴에 대한 대략적인 개념만 잡혔는데, IOCP가 이 패턴을 사용한다고 하니, 어디서 사용하지라고 생각을 좀 해 보았다.
그렇다!! GetQueuedCompletionPort()(이름이 맞나 모르겠다 -_-) 란 놈 빼고는 사용할때가 없는 거다. 지금까지 생각없이 사용했던 GetQueued~()이 Leader/Follower 패턴을 사용하고 있었던 것이다. 그 생각을 하고 나니, IOCP에 대한 구현이나 실제 이 패턴에 대한 내부 구조도 조금은 이해가 되는거 같다.

생각해 보니, 4~5년전쯤에 빌링서버 만들때, 다수 update message를 여러개의 Thread에서 경쟁을 시켜서 message을 획득하게 만든적이 있었는데, 그거랑 비슷한 방식이다. 그 때는 Thread들을 무한 경쟁을 하게 만들었었는데, 이 패턴은 Leader와 Follower를 지정해 주게 되므로서 어느 정도 순차적인 처리가 가능한거 같다..
(사실 잘 모르겠다. 무한 경쟁 시키는 것과, 이 패턴을 사용하는것중 어느게 더 좋은건지.. 내가 모르는 먼가가 있다는거 같다. 이 패턴의 장점이 쓰레드 생성에 드는 비용 감소(poolling이 되므로!), 와 Context Switching비용이 감소 되는데 있다고 하는데.. Context Switching이 적게 드나 보다. Wait하는 Thread가 있으니까 그런거 같다. 그러고 보니 그런것도 같다...)

어쨋거나, 결론적으로 이 Leader/Follower 패턴을 사용하고 싶은데, 직접 구현하기는 귀찮은 사람은, ACE_TP_Reactor를 사용하거나, IOCP를 이용하면 편하게 사용할수 있을것이다. ACE는 무거워서 사용하기 싫고, IOCP역시 직접 구현하기 싫다면, boost::asio::io_service를 사용하면 된다. 이거 역시 내부적으로는 Proactor(Reactor를 사용할수도 있을거 같은데.. 잘 모르겠다)-Win32환경에서는 IOCP로 구현이 되어 있는 것이다. 우하하!!
그것 조차 싫다면, 사용 안해면 된다.. -_-

밑에 소스는 보너스로, 요즘 공부하고 있는 boost::asio에 나오는 priority_handler 예제이다. 요렇게 쓰면, 나도 모르는 사이에 Leader/Follower 사용 유저가 되어 있는 것이다. :) (priority_handler가 어떤 식으로 돌아가는지 모르겠으면 main부분에서 io_service사용부분만 보면 된다)