PostThreadMessage возвращает ERROR_INVALID_THREAD_ID

У меня есть многопоточная симуляция, работающая в Windows Vista. Когда я использую PostThreadMessage для отправки сообщений между потоками, я получаю ERROR_INVALID_THREAD_ID, хотя я совершенно уверен (из-за прохождения через отладчик), что идентификатор потока действителен, и у потока есть очередь сообщений, так как я вызываю PeekMessage из каждого потока после того, как я их создам, как указано в MSDN. Вероятно, целевой поток приостановлен, но, насколько я могу судить, это не должно быть проблемой.

Любые подсказки о том, что попробовать? Я моделирую приложение на основе RTOS, поэтому я надеюсь, что мне не придется вводить слишком много кода, специфичного для Windows.

ИЗМЕНИТЬ –

Еще одна подсказка - если я уберу всю блокировку семафоров, сообщения будут работать нормально (хотя есть некоторые известные условия гонки). Но очереди сообщений не должны зависеть от блокировки потока, верно?

Изменить 2 Код также имеет следующий механизм повторных попыток, предложенный MSDN. Но это все равно не работает - повторная попытка всегда терпит неудачу. хм.....

BOOL bResult = false;
int retry = 0;
DWORD dwError = 0;
do 
{
   bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage);
   if (!bResult)
   {
      dwError = GetLastError();
      retry++;    // should only happen once, if the dest thread has no msg queue
                  // the retry establishes the queue
      Sleep(500);
   }
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue

person Jeff    schedule 06.07.2009    source источник


Ответы (1)


Вы упомянули, что вызываете PeekMessage после создания потоков, но есть ли в этих потоках полные активные циклы обработки сообщений, которые отправляют сообщения? мсдн говорит:

Вызовите PostThreadMessage. Если это не удается, вызовите функцию Sleep и снова вызовите PostThreadMessage. Повторяйте до тех пор, пока PostThreadMessage не завершится успешно.

что звучит немного глупо, если единственное требование состоит в том, чтобы поток вызывал PeekMessage один раз.

Также имейте в виду, что сообщения, размещенные через. PostThreadMessage не отправляется в DispatchMessage. это кажется очевидным, поскольку нет окна для перехода к сообщению, но я видел, как люди делают это, особенно при использовании MsgWaitForMultipleObjects и т.п. для ожидания дескриптора. в этом случае маловероятно, что вы получите ERROR_INVALID_THREAD_ID... скорее всего, вы просто пропустите сообщение.

person Community    schedule 07.07.2009
comment
Спасибо - я должен был упомянуть, что у меня уже есть функция повторной попытки сна в коде. Потоки не имеют связанных с ними оконных объектов, поэтому у них нет традиционных циклов обработки сообщений — я использую MsgWaitForMultipleObjects, используя маску QS_ALLEVENTS, которая возвращается после PostThreadMessage. Интересно, есть ли там что-то не так? я проверю - person Jeff; 07.07.2009
comment
MSDN теперь, похоже, рекомендует создать событие и ожидание этого - person Casebash; 14.02.2011