Конференция "WinAPI" » Объект класса TThread коррекно не завершается [D7, WinXP]
 
  • AndreiDeJavu (17.03.08 14:30) [0]
    Доброго времени суток всем!

    Столкнулся со следующей проблемой,- создаю объект класса TThread (вернее, от класса-наследника :-), запускаю (в его execute всего 1 вызов функции, в которой в свою очередь идут вызовы других функций, создание объектов разных классов и т.д., в основном работа связана с обработкой большого количества файлов, ну и поиском их по папкам). Так вот почему то случайным образом возникает ошибка, после того как я делаю вызов suspend и terminate, приложение подвисает... Ощущение, что это дедлок какой-то. Прошу совета, как это побороть?))) Да, пробовал в таймере с интервалом 1 Мс поставить Application.ProcessMessages,- не помогло... + В другом таймере (с интервалом 1Мс), когда мне нужно завершить поток, вставить
    if (not th.suspended) then th.suspend;
    if (not th.terminated) then th.terminate;


    Не помогло.
  • Сергей М. © (17.03.08 14:32) [1]

    > if (not th.suspended) then th.suspend;
    > if (not th.terminated) then th.terminate;
    > Не помогло.
    >


    А обязано было помочь ?
  • Сергей М. © (17.03.08 14:34) [2]

    > случайным образом возникает ошибка


    В алгоритмике и программировании любая "случайность" есть следствие закономерности)
  • AndreiDeJavu (17.03.08 14:37) [3]
    Ну по идее поток так должен завершиться) В 90% случаях он и завершается... Сергей, может подскажете, что может помочь?))
  • Leonid Troyanovsky © (17.03.08 14:37) [4]

    > AndreiDeJavu   (17.03.08 14:30)  

    > делаю вызов suspend и terminate, приложение подвисает...
    >  Ощущение, что это дедлок какой-то.

    Это называется suspend. Сделай еще resume -
    и будет те щастье.

    --
    Regards, LVT.
  • Сергей М. © (17.03.08 14:48) [5]

    > по идее поток так должен завершиться


    По чьей идее ?


    > что может помочь?


    Помочь может внимательное изучение всего того что происходит при вызовах этих (и многих других) методов поточного класса.

    Suspend "вгоняет" поток в вечную спячку.
    А Terminate всего лишь устанавливает поле FTerminated = True

    Т.е. ты сказал потоку "Засни, зараза !" и после этого требуешь от него каких-то контролируемых им действий)
  • AndreiDeJavu (17.03.08 14:57) [6]
    Leonid, после resume поток возобновляет работу... а мне нужно гарантированно его завершить.

    Сергей, а есть метод или способ работы с этим классом, при котором поток был бы гарантированно "убит", вне зависимости от того, что в нем выполняется и как? То-есть, в любой момент времени я мог бы по клику баттона его обрубить.))
  • Сергей М. © (17.03.08 15:01) [7]

    > AndreiDeJavu   (17.03.08 14:57) [6]


    Есть.
    Но не метод, а стандартная WinAPI-функция TerminateThread().
    По сути ее применение оправдано лишь в аварийных случаях, т.е. в случаях, которые программист по той или иной объективной причине не может предвидеть.
    Сомневаюсь, что тотт самый "аварийный случай" и есть твой случай.
  • AndreiDeJavu (17.03.08 15:13) [8]
    А корректно ли искользовать TerminateThread() при работе с объектом, наследуемым от TThread?
  • Сергей М. © (17.03.08 15:19) [9]
    Ответственность за последствия использования этой ф-ции целиком и полностью лежит на тебе.

    Но еще раз заостряю твое внимание - применение этой ф-ции оправдано только в критических ситуациях. Твои же жалобы на якобы "подвисание" чего-то там без детального изучения и четкого понимания причин этого подвисания не являются поводом для применения этой функции.
  • Leonid Troyanovsky © (17.03.08 15:30) [10]

    > AndreiDeJavu   (17.03.08 15:13) [8]

    > А корректно ли искользовать TerminateThread() при работе
    > с объектом, наследуемым от TThread?

    Пиши корректные функции потока, которые реагируют на Terminate,
    тогда и не будет нужды в TerminateThread.

    А Suspend/Resume - это, во-ще, отладочные функции, в обычной жизни
    их не пользуют.

    --
    Regards, LVT.
  • AndreiDeJavu (17.03.08 15:36) [11]
    Сергей, Leonid,
    Интересно, а как сделать так, чтобы код функций, которые выполняются в потоке, не жил своей жизнью, а реагировал на Terminate?=))  У меня там проводятся довольно емкие вычисления...ProcessMessages не помогает.

    Может Syncronize?))
  • Сергей М. © (17.03.08 15:48) [12]

    > AndreiDeJavu   (17.03.08 15:36) [11]


    > как сделать так, чтобы код функций, которые выполняются
    > в потоке, не жил своей жизнью, а реагировал на Terminate?
    >


    Встречный вопрос - как сделать так, чтобы, к примеру, как можно быстрей узнать о наличии почтовой корреспонденции в своем почтовом ящике ?
  • AndreiDeJavu (17.03.08 15:55) [13]

    > Встречный вопрос - как сделать так, чтобы, к примеру, как
    > можно быстрей узнать о наличии почтовой корреспонденции
    > в своем почтовом ящике ?

    Наверное, жать F5 при веб интерфейсе, или держать программу клиент в свернутой в трее)). Это к тому, что нужно как то опрашивать код, выполняемый в потоке?))) Я понимаю, что это необходимо, но не знаю, как это сделать, как определить, какая именно строчка спустя минуту после запуска  потока выполняется, и как сказать потоку,- стоп, умри.))
  • Сергей М. © (17.03.08 16:05) [14]

    > Наверное, жать F5 при веб интерфейсе, или держать программу
    > клиент в свернутой в трее


    Я вообще-то об обычном почт.ящике, висящем у тебя в подъезде или на калитке)
    Чем чаще ты к нему бегаешь, тем быстрее получишь почту, если ты ее вообще ждешь.

    Не бегаешь - вообще ничего не получишь, за тебя никто туда бегать не будет)


    > как сказать потоку,- стоп, умри


    Прямая аналогия с почтовым ящиком:

    - Со стороны потока-отправителя процедура помещения в ящик корреспонденции выглядит как вызов метода Terminate

    - Со стороны потока-получателя проверка ящика на получение ожидаемой корреспонденции выглядит как булево св-во Terminated.
  • AndreiDeJavu (17.03.08 16:14) [15]
    Сергей,
    procedure th.execute;
     begin
       if not terminated then
           Proceeding( strDirName );
     end;

    Но у меня в Proceeding еще очень много вызовов других функций, те в свою очередь вызывают еще и еще...
    Как они в свою очередь узнают о том, что им пора б закругляться?)
  • Сергей М. © (17.03.08 16:19) [16]

    > Как они в свою очередь узнают о том, что им пора б закругляться?


    Так ничто ж не мешает в телах этих функций обращаться к св-ву Terminated)
  • AndreiDeJavu (17.03.08 17:03) [17]
    То-есть, если функций штук 300... получается просто жесть...)) Ну ладно, спасибо). Буду дописывать.
  • Сергей М. © (17.03.08 17:08) [18]

    > если функций штук 300... получается просто жесть


    > Буду дописывать.


    "Дописывать" надо с умом.
    Проверка на Terminated имеет смысл лишь в длительных по времени алгоритмах, в первую очередь циклических.
  • AndreiDeJavu (17.03.08 18:13) [19]

    > Проверка на Terminated имеет смысл лишь в длительных по
    > времени алгоритмах, в первую очередь циклических.

    Ok)). Так и сделал, вроде все отлично). Спасибо!
 
Конференция "WinAPI" » Объект класса TThread коррекно не завершается [D7, WinXP]
Есть новые Нет новых   [134432   +18][b:0][p:0.001]