Можно ли продвинуть заблокированную тему?застрял в WaitForSingleObject - PullRequest
3 голосов
/ 18 декабря 2011

Если у меня есть приложение, которое создает потоки, которые выполняют свою работу и затем завершают свою работу, и один или несколько потоков попадают в тупик (возможно, не по моей вине!), Есть ли способ программно принудить одного из потоки для продвижения за объектом WaitForSingleObject, в котором он может застрять, и, таким образом, устранение тупика?

Я не хочу прерывать поток, я просто хочу, чтобы он продолжался (и, таким образом, позволял потокам выходить "изящно".

(да, я знаю, это звучит как дубликат моего предыдущего вопроса Delphi 2006 - Какой лучший способ изящно убить поток и при этом запустить обработчик OnTerminate? , но ситуация немного отличается - здесь я спрашиваю, можно ли заставить WaitForSingleObject (Handle, INFINTE) вести себя как WaitForSingleObject (Handle, ItCantPossiblyBeWorkingProperlyAfterThisLong)).

Пожалуйста, будь осторожен со мной.

* ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ *

Проблема не обязательно в коде, источник которого у меня есть. Фактическая ситуация - это библиотека последовательных COM-портов ( AsyncFree ), основанная на потоках. Когда порт основан на USB, библиотека, кажется, имеет тупик между двумя потоками, которые она создает при закрытии порта. Я уже обсуждал это подробно в этом форуме . Я перекодировал один из вызовов WaitForSingleObject, чтобы он не был бесконечным, и это вылечило эту тупиковую ситуацию, но затем другой появился позже в последовательности отключения потока, на этот раз в подпрограмме Delphi TThread.Destroy.

Итак, мое объяснение этому простое: когда мои потоки зашли в тупик, я исправлю код, если смогу. Если я не могу или появляется сообщение, о котором я не знаю, я просто хочу, чтобы нить закончилась. Я не должен быть красивым. Я не могу позволить, чтобы мое приложение задохнулось.

Ответы [ 2 ]

5 голосов
/ 18 декабря 2011

Вы можете сделать дескриптор, используемый в WaitForSingleObject недействительным, закрыв его (из какого-то другого потока).В этом случае WaitForSingleObject должен вернуть WAIT_FAILED, и ваша нить будет "перемещена"

4 голосов
/ 18 декабря 2011

Если вы не используете INFINITE, а просто устанавливаете заданное время ожидания, вы можете проверить, был ли возвращен вызов, потому что истекло время ожидания или потому, что дескриптор, которого вы ждали, попал в сигнальное состояние.Тогда ваш код может решить, что делать дальше.Войдите в другой цикл ожидания или просто выйдите в любом случае, возможно, показывая где-нибудь: «Эй, я ждал, но это было слишком долго, и я все равно прекратил работу).Другой вариант - использовать WaitForMultipleObjects и использовать нечто подобное событию, чтобы при необходимости завершить ожидание.Преимущество не требует тайм-аута, чтобы истечь.Конечно, один поток, который пробуждается, должен уметь обрабатывать «исключительное» условие продолжения, даже если «основной» дескриптор, которого он ожидал, не вернулся вовремя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...