출처: 온라인서버제작자모임
Proactor
정의
- reactor와 같이 비동기 I/O 방식의 하나.
- I/O 명령이 OS 수준에서 이루어 진다는 점이 reactor와 다른점.
- reactor 는 이벤트 발생을 통보 받고 명령을 수행해야 하지만 proactor는 명령을 먼저 내리고(give an order) 이벤트가 발생하면 명령이 완료되었음을 통보 받는다.
- windows에서는 IOCP 루틴을 사용하기 때문에 성능이 좋음.
- reactor 방식의 웹서버
- reactor에 accept 이벤트 등록
- 초기화
- connect
- reactor에서 acceptor에 이벤트 발생을 통보
- HTTP Handler 생성
- HTTP Handler에서 read/close 이벤트를 reactor에 등록
- read / close 이벤트 발생시 reactor에서 HTTP Handler로 이벤트 발생을 통보
- proactor 방식의 웹서버
- Web Server에서 acceptor 를 초기화
- acceptor에서 OS에 asynch accept 작업을 초기화
- Web Server는 proactor 이벤트 루프를 호출한다.
- connect
- OS에서 proactor에 accept 작업이 완료되었음을 통보
- proactor에서 acceptor에 작업이 완료되었음을 통보
- HTTP Handler 생성
- HTTP Handler는 asynch read 작업을 초기화 한다.
- proactor 예제
ACE_Proactor : 완료 handling 을 운용하는 작업을 함.
- proactor_run_event_loop() : 완료 이벤트 발생을 기다리면서 이벤트들을 다중 수신하여 각각의 완료 핸들러의 적당한 훅 메소드를 호출해 줌
- proactor_end_event_loop() : 모든 proactor_run_event_loop의 루프를 종료시켜 줌.
- ACE_Asynch_Read_Stream : 소켓에 읽기 명령을 초기화 하기 위한 class.
- ACE_Asynch_Write_Stream : 소켓에 쓰기 명령을 초기화 하기 위한 class.
ACE_Message_Block : 메세지를 효과적으로 저장하고 공유하는 데 사용할 수 있는 효율적인 데이터 컨테이너. 범용적으로 사용 할 수 있음.
- composite 패턴 : 개별객체와 복합객체를 같은 방식으로 다룰수 있는 방법을 제공.(Head First Design Pattern p.394)
- cont() : 조합 메세지 구성을 위한 메소드. ACE_Message_Block을 링크드 리스트 형식으로 만들수 있음. C++NPv1 [그림 4.2]
- rd_ptr() / wr_ptr() : 데이터를 읽거나 쓸때 사용하는 포인터. read/write 후 포인터를 반드시 전진 시켜 줘야 함
- memcpy( block.wr_ptr(), recv_ptr, recv_size);
- block.wr_ptr(recv_size);
- base() : 얕은 복사(Shallow copy)
- copy() : 깊은 복사(Deep copy). 메세지 블럭안으로 데이터를 복사할 때 사용
- release() : 레퍼런스 카운트 1 감소. 0 이면 자원들을 해제.
- 받은 패킷을 저장하는 용도로 사용할 수 있음
- ACE_Message_Queue와 함께 사용 : ACE_Message_Block을 element로 가지는 Queue. 잠금 정책을 선택적으로 사용가능.
Thread
ACE_Thread_Manager 방식
- 스레드 함수를 함수 포인터 방식으로 넘겨줌. CreateThread 와 비슷.
- 한번의 호출로 여러 스레드를 동시에 생성, 종료 할 수 있음.
- C방식
- ACE_Thread_Manager 예제
ACE_Task 방식
- ACE_Task_Base 클래스가 스레드가 되는 OOP 방식
- ACE_Task_Base.activate() 를 호출하면 svc() 메소드가 호출됨.(동기적인 방식에 의해 호출되는 것은 아님)
- Active Object : 모든 Active Object는 객체상에서 클라이언트가 호출한 메소드를 실행하는 데 사용되는 내부 스레드를 가지고 있음.
- ACE_Task_Base 예제
activate() 의 스레드 생성 옵션
- APG page 320. [표 13.1]
- 보통 (THR_NEW_LWP) 혹은 (THR_NEW_LWP | THR_JOINABLE) 사용.
- 하나의 클래스에서 다수의 스레드를 생성할 수도 있다.(통합 관리 하려면 THR_JOINABLE 옵션을 사용해야 함)
- 우아하게 종료하기 예제.
- ACE_Task_Base 클래스를 이용해 proactor pool이나 reactor pool을 만들어 사용할 수 있다.
LOG
- 간단한 향식의 로그 사용 예제 : ACE_DEBUG, ACE_ERROR
로깅 포맷 지시자 : APG page.70 [표 3.2]
- %P : 현재 프로세스 ID
- %t : 호출한 스레드 ID
- %N : 호출한 위치의 소스 파일 path
- %l : 호출한 위치의 소스 라인
- %D : 날짜 시간
- 로깅 포맷 지시자 예제
로깅 출력 방식 변경 : APG page.87 [표 3.5]
- STDERR : 표준 오류 스트림에 출력
- OSTREAM : 지정한 출력 스트림에 기록
- MSG_CALLBACK : 역호출 객체(callback)를 통해 메세지 출력
- 로깅 출력 방식 변경 예제
발표자료
'프로그래밍' 카테고리의 다른 글
A reusable, high performance, socket server class (0) | 2012.08.16 |
---|---|
[펌] 소켓 프로그래밍에 관한 주의 및 Q&A (0) | 2012.08.16 |
[펌] ACE 강의(1) (0) | 2012.08.13 |
[펌] ACE_Message_Block Pool 만들기 (0) | 2012.08.13 |
[펌] Boost 로 C++0x의 라이브러리 「TR1」을 미리 사용 해 보 자 (5) (0) | 2012.08.13 |