1

여러 가지 응용 프로그램을 만들었습니다. 응용 프로그램 윈도우 (W [n] : TMyWindows)는 모두 동일하며 모두 그들과 연관된 개인 객체 클래스 인스턴스 (E : TMyObject)를 가지고 있습니다. 자식 창은이 개체를 통해 일부 메시지를 생성합니다. 메인 애플리케이션에서 메시지 내용에 따라이 메시지를 처리하는 두 개의 스레드를 만들었습니다.델파이 2006의 포스트 스레드 메시지 및 peekmessage 문제

while not terminated do 
begin 
... 
if peekmessage(msg,0,thread1message_1,thread1message_n,pm_remove) then 
     process message 
do other things; 
end 
: 내가 그런 일을 각 스레드의 실행 방법에있어서,

W[1].E.Service(thread1service) 
W[2].E.Service(thread2service) 

TMyObject.Service (ServiceType 자리가) 이제

case servicetype of 
    thread1service: PostThreadMessage(thread1id,...); 
    thread2service: PostThreadMessage(thread2id,...); 
end; 

입니다 : 예를 들어 다음과 같은 비동기 호출을 할 수 있습니다

두 번째 스레드가 메시지를받지 못하는 경우 모두 예외가 발생합니다. 이유가 궁금하십니까?

답변

1

PeekMessage()에 제공하는 범위가 유효한지 확인해야합니다. 이 같은 모든 메시지를 수신하는 대신에 0을 넣어보십시오 :

PeekMessage(msg, 0, 0, 0, PM_REMOVE) 

를 문제가 해결되지 않으면, 내가 PostThreadMessage() 함수의 결과를 확인할 것 ... 그것은 스레드가 PeekMessage() 호출되지 것을 할 수있다 그렇다고해서 Windows가 메시지 대기열을 만들 것을 요구합니다.

("주의"에서) this article에 명시된 바와 같이

, 당신은 PostThreadMessage()에 호출의 결과를 확인하고 Sleep()를 실패하면, 또는 자식 스레드에 대한 준비가되어 있음을 메인 스레드에 알리기 위해 이벤트를 사용할 수 있습니다 메시지를받습니다. 그래서, 내가 어떤 합리적인 설명을 찾을 수 없습니다로 포기했다

N

0

@

HTH.

처리 할 메시지가있는 작업 스레드에 알리기 위해 이벤트 신호와 함께 중요한 섹션을 사용하여 메시지를 보내기로 결정했습니다. 불행하게도 이것은 메인 쓰레드가 새로운 쓰레드를 보내기 전에 작업 쓰레드가 어떤 메시지를 처리했는지 확인해야한다는 것을 의미한다.

+0

반드시 그렇지는 않습니다. 각 스레드에 임계 구역으로 보호되는 FIFO 대기열을 지정하고 대기 할 이벤트를 추가하십시오.FIFO가 비어 있지 않을 때 이벤트를 신호합니다. – mghie

+0

나는 그것에 대해 생각했다. 그러나 주 스레드가 대기열에 많은 마사지를 걸면 작업 스레드는이를 처리해야하고 작업 스레드는 그의 루프에서 중요한 작업을 수행한다. 따라서 작업중인 스레드가 메시지를 처리하고 있다면 주 스레드는 새 메시지를 작동중인 스레드로 보내는 대신 덤프합니다. – zoomz

+0

정말 슬픈 메시지 메시지 큐가 이상적이었을 것입니다. 나는 왜 그것이 당신을 위해 작동하지 않는지 궁금해. 나는 이것에 대한 나의 구현을 점검했고, 당신이 말하는 것을 잘못한 것처럼 보이지 않는다. :( – Nat

0

저는 이것이 오래된 질문이라는 것을 알고 있습니다 만, 나는 우리 코드에서 비슷한 문제를 가지고 있습니다. 우리는 Win 7 64 비트에서 Delphi 2006을 실행 중입니다. 문제의 코드는 peekmessage/postthreadmessage를 통해 별도의 응용 프로그램과 통신하는 DLL과 관련됩니다.

필자는 궁극적으로 응용 프로그램이나 Delphi에 대한 관리자 권한 부여 문제를 추적 할 수있었습니다. 또한 호환성 모드에서는 관리자 권한이 부여되어야하므로 문제가 발생합니다. 관리자 권한이 부여되면 관리자 스레드는 비 관리자 스레드와 통신 할 수 있지만 비 관리자 스레드는 관리자 권한으로 스레드에 메시지를 다시 게시 할 수 없습니다. 관리자가 아닌 앱의 PostThreadMessage 호출이 성공을보고했지만 메시지가 대상 앱의 메시지 대기열에 표시되지 않았습니다.

문제를 해결하지는 못했지만 다행스럽게도 정상 모드에서 응용 프로그램을 실행할 수 있으므로 문제를 해결하는 데 시간이 많이 걸렸습니다.