(아래의 Effo EDIT를 참조하십시오.이 부분은 더 이상 사용되지 않습니다) 스레드와 각 UI 사이에 대기열이 있으면 링 버퍼가 필요하지 않습니다. 메시지가 도착했을 때
, 스레드는 팝과 그에 따라 UI의 큐에 밀어 넣습니다.
또한 각 UI.Q는 원자 적으로도 작동 될 수 있습니다. 뮤텍스가 필요하지 않습니다. 또 다른 이점은 각 메시지가 두 번만 복사되었다는 것입니다. 하나는 낮은 수준의 큐에, 다른 하나는 디스플레이에, 다른 곳에 메시지를 저장하는 것은 필요하지 않습니다 (낮은 수준의 큐에서 UI.Q에 포인터를 할당하면 충분합니다. C/C++의 경우).
메시징 트래픽이 많은 경우 UI.Q의 길이가 실행 시간만큼 길지 않을 수도 있습니다. 이 질문에 따라 동적 길이 큐를 사용하거나 UI 자체가 오버플로 된 메시지를 posix 메모리 매핑 파일에 저장하도록 할 수 있습니다. 파일을 사용하고 여분의 메시지를 복사해야하는 경우에도 posix 매핑을 사용하면 효율성이 높습니다. 그러나 어쨌든 그것은 예외 처리 일뿐입니다. 대기열을 적절한 크기로 설정하면 일반적으로 우수한 성능을 얻을 수 있습니다. 요점은 UI가 오버 플로우 된 메시지를 매핑 된 파일에 저장해야 할 때 낮은 수준의 큐에 영향을주지 않도록 동시 작업을 수행해야한다는 것입니다.
나는 동적 크기 대기열 제안을 선호합니다. 우리는 현대 PC에 많은 기억을 가지고있는 것 같습니다.
EffoNetMsg.pdf (http://code.google.com/p/effonetmsg/downloads/list) 문서에서 잠금없는 대기열 기능 및 동시성이 높은 프로그래밍 모델에 대해 자세히 알아보십시오.
Effo EDIT @ 2009oct23 : 메시지 뷰어를 스크롤하기위한 임의 메시지 액세스를 지원하는 스테이지 모델을 표시합니다.
+---------------+
+---> Ring Buffer-1 <---+
| +---------------+ |
+--+ +-----+
| | +---------------+ | |
| +---> Ring Buffer-2 <---+ |
| +---------------+ |
| |
+-------+-------+ +-----------+----------+
| Push Msg & | | GetHeadTail() |
| Send AckReq | | & Send UpdateReq |
+---------------+ +----------------------+
|App.MsgStage() | | App.DisPlayStage() |
+-------+-------+ +-----------+----------+
| Pop() | Pop()
^ +-V-+ +-V-+
| Events | Q | Msg Stage | | Q | Display Stage
| Go Up | 0 | Logic-Half | | 1 | Logic-Half
-+------------- | | -------------+------------ | | ---------------
| Requests | | I/O-Half | | | I/O-Half
| Move Down +-^-+ | +-^-+
V | Push() |
+--------------+-------------+ |
| Push OnRecv Event, | +-------+-------+
| 1 Event per message | | | Push()
| | +------+------+ +------+------+
| Epoll I/O thread for | |Push OnTimer | |Push OnTimer |
|multi-messaging connections | | Event/UI-1 | | Event/UI-2 |
+------^-------^--------^----+ +------+------+ +------+------+
| | | | |
Incoming msg1 msg2 msg3 Msg Viewer-1 Msg Viewer-2
점 :
이
1 당신은 다른 고도의 동시 모델, 위의 그림과 같이 특정 단계적 모델을 이해; 왜 빨리 실행되는지 알 수 있습니다.
2 C/C++ 및 GNU Linux 2.6x의 경우 두 가지 I/O 유형 중 하나가 Messaging 또는 Epoll 스레드입니다. 다른 하나는 그림 그리기 또는 텍스트 인쇄와 같은 표시입니다. 2 종류의 I/O는 2 단계로 처리됩니다. Win/MSVC의 경우 Epoll 대신 Completion Port를 사용하십시오.
3 아직까지 언급 한 것처럼 2 개의 메시지 전송. a) Push-OnRecv는 메시지를 생성합니다 (C/C++의 경우 "CMsg * pMsg = CreateMsg (msg)"). b) UI는 그에 따라 링 버퍼에서 메시지를 읽고 복사하며, 전체 버퍼가 아닌 업데이트 된 메시지 부분 만 복사하면됩니다. 참고 대기열 및 링 버퍼는 메시지 핸들 (C/C++의 경우 "queue.push (pMsg)"또는 "RingBuff.push (pMsg)"만 저장하고 오래된 메시지는 삭제합니다 ("pMsg-> Destroy() "C/C++ 인 경우). 일반적으로 MsgStage()는 메시지 헤더를 링 버퍼에 넣기 전에 다시 작성합니다.
4 OnTimer 이벤트가 발생하면 UI는 링 버프의 새로운 헤드/테일 표시기가 포함 된 상위 레이어에서 업데이트를 수신합니다. UI는 이에 따라 디스플레이를 업데이트 할 수 있습니다. Hope UI에는 로컬 msg 버퍼가 있으므로 전체 링 버퍼를 복사 할 필요는 없지만 업데이트 만하면됩니다. 위의 3 번을보십시오. 링 버퍼에서 임의 액세스를 수행해야하는 경우 UI에서 OnScroll 이벤트를 생성하도록 할 수 있습니다. 실제로 UI에 로컬 버퍼가 있으면 OnScroll이 필요하지 않을 수 있습니다. 어쨌든, 당신은 그것을 할 수 있습니다. Note UI는 OnAgedOut 이벤트 생성과 같이 수명이 만료 된 메시지를 버릴 것인지 여부를 결정하여 링 버퍼가 정확하고 안전하게 작동 할 수 있도록합니다.
5 정확히 OnTimer 또는 OnRecv가 이벤트 이름이며 DisplayStage() 또는 MsgStage()에서 OnTimer() {} 또는 OnRecv() {}가 실행됩니다. 다시, 이벤트는 위쪽으로 이동하고 요청은 다운 스트림으로 이동합니다. 이것은 이전에 보았던 것과 다를 수 있습니다.
6 Q0 및 2 개의 링 버퍼는 단일 제작자 및 단일 소비자이므로 퍼포먼스를 향상시키기 위해 잠금없는 기능으로 구현 될 수 있습니다. 잠금/뮤텍스는 필요하지 않습니다. Q1은 뭔가 다르다. 하지만 위의 디자인 그림을 약간 변경하여 단일 제작자와 단일 소비자로도 전환 할 수 있다고 생각합니다. 모든 UI가 대기열을 갖도록 Q2를 추가하면 DisplayStage()는 Q1 및 Q2를 폴링하여 모든 이벤트를 올바르게 처리 할 수 있습니다. 참고 Q0과 Q1은 Event-Queue이며 Request-Queues는 위의 그림에 표시되지 않습니다.
7 MsgStage() 및 DisplayStage()는 하나의 StagedModel.Stage()에 순차적으로 있습니다 (예 : 메인 스레드). Epoll I/O 또는 Messaging은 다른 스레드 인 MsgIO Thread이며 모든 UI에는 I/O 스레드가 있습니다 (예 : Display Thread). 위의 그림에서 총 4 개의 스레드가 동시에 실행됩니다. Effo는 다중 라이저와 수천 개의 메시징 클라이언트에 대해 단 하나의 MsgIO Thread가 충분해야 함을 테스트했습니다.
높은 동시성 프로그래밍 모델 및 네트워크 메시징에 대한 자세한 내용은 EffoNetMsg.pdf http://code.google.com/p/effonetmsg/downloads/list 또는 EffoAddons.pdf http://code.google.com/p/effoaddon/downloads/list 문서를 참조하십시오. 잠금 해제 대기열 및 잠금 장치가없는 링 버퍼와 같은 잠금 해제 기능에 대한 자세한 내용은 EffoDesign_LockFree.pdf (http://code.google.com/p/effocore/downloads/list)를 참조하십시오.
예, 디스플레이 코드와 함께 UI.Q를 함께 배치하면 상황이 더 쉬울 것입니다. 오버플로 (overflow)시 오래된 자료가 삭제되어 순환 버퍼로 사용하는 것이 가장 좋습니다. UI는 윈도우 스크롤 업/다운을 위해 UI.Q의 임의의 부분에 무작위로 액세스해야합니다. 잠금 해제 대기열 정보를 살펴 보겠습니다. – hplbsh
내 업데이트보기, 위 그림. – Test