1 기타 #
- DLL 로딩때는 다른거 필요없다. handle_ = ACE_DLL_Manager::instance()->open_dll(DLL화일명, RTLD_NOW, 0);구문이 가장 깔끔하다. find_dll(DLL화일명) 메소드로 이미 로딩되었는지 확인할 수 있고, unload_dll(handle_)로 해제하면 된다.
- ACE_Message_Queue : clone() - 완전히 새로운 복사본 생성, duplicate() - 레퍼런스 카운팅을 사용한 "가짜" 복사 실행
- 대부분의 경우 duplicate()로도 충분. 왜냐면 별도의 메모리를 차지하지 않고 처리를 할 수 있기 때문. clone()보다는 효율적이라고 생각됨.
- 비동기 입출력을 수행할때, 해당 클라이언트를 대표하는 객체내부에 소켓에 해당하는 클래스의 인스턴스 포인터를 놓게되는데, 이때 ACE_Async_Sock_Stream과 같은 클래스의 인스턴스 포인터를 사용하지 말고, 핸들러 자체의 인스턴스 포인터를 등록해서 사용하는 것이 좋다. -> 이것은 proactor의 특성상 핸들러를 재활용하므로 특정 연결이 핸들러 포인터를 소유할 수 없게 된다. 다르게 작성해야함. -_-;
- ACE_Time_Value의 생성자와 set() 메소드의 두번째 매개변수값이 microsecond(100만분의 1초. O.o)라는 점에 주의! millisecond(1000분의 1초)로 지정하려면 msec() 메소드를 사용할 것. (이것때문에 타임아웃 설정시 많이 헛갈림... -_-;)
- 바이트순서를 알려면? ACE_CDR_BYTE_ORDER가 1인지 아닌지를 검사. 1이면 little endian(인텔x86), 0이면 big endian(모토롤라, RISC등등). "CDR_stream.h" include해야함.
- ACE_OutputCDR, ACE_InputCDR을 사용할 때, 생성자 매개변수에 바이트 순서를 지정하는 부분이 있는데, 이부분값은 ACE_CDR_BYTE_ORDER 규칙에 따른다. (지정안하면 ACE_CDR_BYTE_ORDER로 지정되며, 당연히 특정 바이트 순서로 정렬하고 싶으면 기입하면 된다) 이는 어플리케이션 프로토콜 설계시 특정 바이트 순서만을 지정하고 싶을때 유용하다.
- 자동으로 변환해주는 점이 너무 편하다.
별로 할게 없다.
- 자동으로 변환해주는 점이 너무 편하다.
- ACE_Reactor에서 타이머를 사용할 때, 스케줄링은 쉽지만 취소에는 주의를 기울여야한다. 매번 schedule_timer()메소드를 호출할때마다 타이머id를 반환받게되는데, 이중 일부만 취소하려면 cancel_timer(long timer_id,...)를 사용하는 것이 좋고, 해당 핸들러 전체에 할당된 타이머들을 취소하려면 cancel_timer( ACE_Event_Handler* event_handler,...)을 사용하는 것이 좋다.
- 즉, 하나의 핸들러에 여러 종류의 타임아웃을 걸 수 있다. 하지만 반드시취소해주어야만 한다. (안그러면 보호오류발생!)
- 즉, 하나의 핸들러에 여러 종류의 타임아웃을 걸 수 있다. 하지만 반드시취소해주어야만 한다. (안그러면 보호오류발생!)
- ACE_INET_Addr에서 "192.168.0.1:4444"와 같은 형태로 주소문자열을 얻으려면 ACE_INET_Addr::addr_to_string() 메소드를 사용하면 된다. (마지막 매개변수를 1로 놓아야한다. 0으로 놓으면 "localhost:4444" 이런식으로 출력이 된다.)
- 메세지 큐가 필요없는 쓰레드 객체를 만들고 싶으면 ACE_Task_Base 클래스에서 상속받아 구현한다. ACE_Task는 간단한 쓰레딩을 구현하기에는 좀 무거운 맛이 있다.
- ACE의 디버그 로깅기능중 화일에 저장하려면 iostream의 ofstream을 사용하게 되는데, 이를 사용하려면 ACE 라이브러리 빌드시 ACE_HAS_STANDARD_CPP_LIBRARY 가 1로 #define되어있어야 한다. 그렇지 않으면 ACE_LOG_MSG->msg_ostream() 에 대한 링크 에러가 발생한다.
- win32 GetTickCount()와 비슷한 역할을 하는 함수는 ACE_OS::gettimeofday()함수가 있다. 하지만 가능하다면 ACE_High_Res_Timer::gettimeofday_hr()을 사용하는 것이 좋다. (이것이 더 정확하다)
- 화일명 변경은 ACE_OS::rename(), 화일 삭제는 ACE_OS::unlink() 로 하면 된다.
2 일반적인 동기화 장치 성능의 비교 및 평가 #
운영체계는 다양한 어플리케이션의 요구들을 다루기위한 동기화 장치들을 제공한다. 이 장에서 다루는 동기화 장치들은 하드웨어나 운영체계 구현에 따라 그 성능이 다양하게 나타난다 하더라도, 일반적으로 고려되는 사항들은 다음과 같다.
- 상태 변수(Conditional Values)와 세마포어는 종종 뮤텍스보다 높은 과부하를 가지는데, 이는 그 내부구조가 뮤택스보다 더 복잡하게 구현되어있기 때문이다. 어쨌거나, 운영체계에 구현된 동기화 장치들은 내부적인 운영체계와 하드웨어적인 최적화 작업에 따른 잇점을 가질 수 있기 때문에, 개발자가 직접 구현한 대체 장치보다 언제나 보다더 효율적으로 실행된다.
- 뮤택스는 일반적으로 'reader/writer 잠금'보다 더 낮은 부하를 가지는데, 이는 여러 개의 대기정보를 가지고 있는 집합(waiter set)을 관리할 필요가 없기 때문이다. 그렇지만, 다중 reader 쓰레드는 병렬로 실행을 진행할 수 있으므로, 정보를 수정하는 것보다 정보를 읽어들이는 것이 훨씬 더 많이 발생하는 경우에는 다중 프로세서하에서의 'reader/writer 잠금'이 더 효율적으로 평가될 수 있다.
- 비재귀적 뮤택스는 재귀적 뮤택스보다 더 효율적이다. 게다가, 재귀적 뮤택스는 이를 해제하는 것을 개발자가 잊었을 경우 보이지 않는 잠재적인 버그의 원인이 될 수 있다. (But97) 이것은 비재귀적 뮤택스에서는 이러한 문제발생시에 즉시 데드락에 들어감으로써 그것을 드러내는 것과는 대조적이라고 할 수 있다.








![[http]](/wiki/imgs/http.png)
