2009-02-04 6 views
5

델파이 5에서 인디 9를 사용합니다. 제 애플리케이션에서 UDP를 통해 네트워크 장치와 통신하고 싶습니다. 그래서 저는 UDPServer comp를 사용합니다. TThread에서 파생 된 클래스입니다. 다음 코드와 비슷하게 작성할 때 CPU 사용량은 100 %입니다. 스레드에서델파이에서 100 % CPU 사용량

:

while not terminated do begin 
    if GetMessage(Msg, 0, 0, 0) then begin 
    if Msg.message = WM_UDPMSG then 
     Break 
    else 
     DispatchMessage(Msg); 
    end; 
end; 

및 OnUDPRead 이벤트 : 나는 동안-DO 루프 또는 OnUDPRead 이벤트 절전 모드 기능을 사용하면

try  
    // Processing the data here 
    except 
    PostThreadMessage(ThreadId, WM_UDPMSG, 0, 0); 
    end; 

는 변화가 없다. 여전히 CPU 사용량은 100 %입니다.

내 스레드 우선 순위가 보통입니다.

문제를 어떻게 해결할 수 있습니까?

답변

6

GUI 스레드에서 UDP 데이터를 받고 있지만 다른 스레드에서 데이터를 처리하려고하므로 문제가 있습니다.

실제로 문제는 비동기 구성 요소를 차단 방식으로 사용하려고한다는 것입니다. 더 좋은 해결책은 synapse과 같은 실제 블로킹 UDP 통신 라이브러리를 사용하는 것입니다. 그런 다음 새 데이터가 스레드에서 수신 될 때까지 기다리는 것은 매우 쉽습니다.

당신은 쓸 수 : 대답에 대한

while not Terminated do 
begin 
    BytesRead := FSocker.RecvBufferEx(@(Buffer[0]), BufferSize, Timeout); 
    if (BytesRead = 0) then 
    begin 
    // continue or exit if the receiving Failed 
    case FSocket.LastError of 
     0, WSAETIMEDOUT: Continue; 
     WSAECONNRESET, WSAENETRESET, 
     WSAENOTCONN, WSAECONNABORTED, 
     WSAENETDOWN: 
     begin 
      CloseConnection; 
      Exit; 
     end; 
    else 
     CloseConnection; 
     Exit; 
    end;  
    end; 
    // process the data in the buffer 
end; 
+0

GetMessage가 이미 차단되어 있으므로 세마포가 필요하지 않습니다. –

+0

@ TheFox : 당신의 권리, 나는 그것에 대해 완전히 잊었다! (내가 창 메시지 시스템에 직접 프로그래밍 한 이후로 한참 동안). 내 대답에서 그 부분을 추출했습니다. –

+0

감사합니다 The_Fox 및 Davy Landman – SimaWB

3

델파이 코드와 친숙하지 않지만 CPU를 연마하는 busy-wait 메커니즘을 실행하고 있습니다.

루프에 수면이나 지연을 추가하면 문제가 숨겨집니다. 나는 당신의 메시지/이벤트를받는 더 좋은 방법을 사용하는 것이 좋습니다. 관찰자 - 청취자 패턴 또는 스레드 대기 및 통지 스키마와 같은 많은 솔루션이 있습니다. 귀하의 코멘트에 응답


일부 유용한 링크 :

+0

감사합니다. "많은 솔루션이 있습니다"예나 링크가 있습니까? – SimaWB

+0

문제 없습니다. –

+0

에 대한 링크를 추가했습니다. 그가 게시 한 코드에서 busy-wait 메커니즘을 사용하고 있다는 것을 확신하지 못합니다. 메시지가있을 때까지 GetMessage 블록을 처리하므로 대기 중이 지 않습니다. 그는 또한 수면이 도움이되지 않는다고 말합니다. 심지어 수면 (1)은 CPU 사용량을 0-1 %로합니다. 그의 문제는 어딘가에있다. –

1

는 메시지가 도착할 때까지 (블록 스레드)를 대기 GetMessage 함수의 버전이 있습니까?

+0

GetMessage는 스레드를 차단하지만 PeekMessage는 스레드를 차단하지 않습니다. –

1

나는 GetMassage의 verison을 모른다. 그러나 Windows에서 이렇게 선언했습니다.

function GetMessage; external user32 name 'GetMessageA'; 
+0

GetMassage? 아, 단지 ... –

2

1 Indy의 버전이 9.0.0.18 이상이어야합니다. 오래된 것들은 진행중인 스레딩 버그를 가지고 있습니다. 여기에는 델파이 버전 7까지 제공되는 모든 버전의 인디가 포함됩니다.

2 인디와 함께 작업하는 방법에 대한 샘플 코드를 살펴보십시오.

http://www.indyproject.org/demos/index.html

+0

+1 마침내 서버 구성 요소의 경우. 서버 구성 요소 중 일부는 멀티 코어 또는 HT 시스템에서 실행되는 경우 18보다 이전 버전에서 이상하게 작동합니다. (그리고 그 HT와 함께 싱글 코어 P4를 포함) –

0

이 프로젝트는 매우 큰 프로젝트입니다. 그래서 Indy를 업데이트하는 것이 어렵습니다. 그러나 문제가 Indy의 이전 버전 때문에 확실하다면, 나는 그것을 업데이트 할 것입니다.

나는 모든 Indy 데모를 보았다. 이 데모는 매우 간단합니다. 내 프로젝트에서 나는 매우 빠른 데이터 전송을했습니다. (실시간 사운드 레코더와 마찬가지로)

+0

당신의 애플 리케이션을 추락시키지 않으려면 Indy를 업데이트해야합니다. 나는 1 시간 안에 Indy 앱을 안정적으로 추락시킬 수 있었다. –