Home // Blog
Home // Notice
Home // Tag Log
Home // Location Log
Home // Media Log
Home // GuestBook
Inter-thread communication in C++ #8
Posted at 2008. 11. 6. 00:11 //
in S/W개발/C++ 이야기 //
by
설계 결함이 또 발견돼서 수정했습니다. 거의 매일 같이 major change가 발생하네요. 이게 다 C++ class library 설계 경험이 부족한 탓인 것 같습니다.
이번에 바뀐 내용은 다음과 같습니다.
s = "btn_handler";
ButtonHandlerITCAdaptor btnHdlr(
shared_ptr<ButtonHandler>(new ButtonHandler()), s);
btnHdlr.doIt(&ButtonHandler::onClick, 10, 20);
btnHdlr.quit();
btnHdlr.join();
즉, Caller쪽에서는 ButtonHandler 객체를 가리키는 포인터를 유지하지 않는 것이죠.
소스 코드 첨부하니 참고하시기 바랍니다.
이번에 바뀐 내용은 다음과 같습니다.
- ITCThread의 세가지 사용 모드 즉, 상속 모드, 기존 클래스 조합 모드, 일반 함수 호출 모드 이렇게 세가지를 ITCThread 만 가지고 처리하던 걸 이제는 ITCThread, ITCAdaptor, FunctionITCAdaptor로 분리해서(ITCAdaptor를 없애 버렸었고, FunctionITCAdaptor는 ITCThread에서 상속받고 있었지요) 지원하고, 이 세 클래스의 Base 클래스로 ITCThreadBase를 만들었습니다. ITCThreadBase를 만든 이유는 템플릿으로 인한 code bloat를 방지하기 위함입니다.
- 그전에는 세 가지 모드를 지원하기 위한 멤버 함수를 ITCThread에 모두 정의해 놓고 있었는데, 이제는 각 세가지 모드를 담당하는 클래스에 골고루 분배해 놓았습니다. 이렇게 하면서 그전에 있던 심각한 설계 결함이 해결됐습니다. ITCThread안에서 Callee 객체를 release 하지 못하는 결함이었습니다. 실은 이 문제는 ITCThread와 ITCAdaptor를 하나로 합쳐 놓았기 때문에 발생하는 문제이기도 했습니다. ITCThread는 상속을 통해서 새로운 ITCThread의 파생 클래스를 정의하기 위한 클래스인데, 이 경우 Callee는 파생 클래스 인스턴스가 되어버리고 기본 클래스의 dtor에서 파생 클래스의 dtor를 호출할 수는 없는 일이기 때문입니다. 그래서 기존에는 기존 클래스 조합 모드(지금은 ITCAdaptor를 사용합니다)에서 Callee 객체를 넘겨주고 나서 그 객체의 ownership을 ITCThread에게 주지 못하고, Caller쪽에서 직접 삭제해야 하는 문제가 있었습니다. 기존에는 다음과 같이 했었는데,
- s = "hello";
Hello* h = new Hello();
HelloITCAdaptor hello(h, s);
for (int i = 0; i < 1000; ++i)
{
hello.sayHelloTo("Yoonsoo Kim");
}
hello.quit();
hello.join();
delete h;
- 이제는 다음과 같이 하면 됩니다.
- // example #3
s = "hello";
HelloITCAdaptor hello(shared_ptr<Hello>(new Hello()), s);
for (int i = 0; i < 1000; ++i)
{
hello.sayHelloTo("Yoonsoo Kim");
}
hello.quit();
hello.join(); - ITCThreadBase::queue(CallType call) 이 추가되었습니다. 원한다면 사용자가 ITCThreadBase::queue()와 bind를 적절히 이용해서 어떤 멤버 함수던 그냥 함수던 호출할 수가 있습니다. DoIt() 보다는 low-level 이기 때문에 상당히 사용하기가 불편합니다.
- 이 외에 이런 저런 code cleanup을 했습니다.
s = "btn_handler";
ButtonHandlerITCAdaptor btnHdlr(
shared_ptr<ButtonHandler>(new ButtonHandler()), s);
btnHdlr.doIt(&ButtonHandler::onClick, 10, 20);
btnHdlr.quit();
btnHdlr.join();
즉, Caller쪽에서는 ButtonHandler 객체를 가리키는 포인터를 유지하지 않는 것이죠.
소스 코드 첨부하니 참고하시기 바랍니다.