Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.12.2010, 00:29   #1
abb777
 
Регистрация: 17.12.2010
Сообщений: 6
По умолчанию Потоки - проблема с закрытием программы

Hi, All,

Есть наследник от TThread и список объектов, в каждом из которых создается экземпляр этого наследника. Еще каждый объект списка содержит событие (Event), созданное при помощи CreateEvent(). Суть в том, что все объекты списка связаны через взаимную генерацию этих событий. Т.е. Каждый объект ожидает события при помощи WaitForSingleObject(), работает и генерирует событие для другого объекта. И так в цикле. Все работает прекрасно, если дать этой системе доработать до конца метода Execute каждого потока. Но при попытке прервать работу всех потоков, например, при закрытии окна программы, все виснет. Причем несколько потоков все-таки завершается корректно, а остальные виснут на WaitForSingleObjject(), хотя там используется таймаут, а не бесконечное ожидание.

Вот код Execute:

Код:
procedure TLayerThread.Execute;
begin
  FLayer.FCurStep := 0;
  FLayer.FIsActive := true;
  while true do
  begin
    // принудительный выход
    if Terminated or
       FLayer.FTerminating or
       (FLayer.FEvent = INVALID_HANDLE_VALUE) then break;
..........................
      repeat
        //
        if Terminated or
           FLayer.FTerminating or
           (FLayer.FEvent = INVALID_HANDLE_VALUE) then break;
        Fres := WaitForSingleObject(FLayer.FEvent, 100);
      until Fres <> WAIT_TIMEOUT;
............................
  end;
  FLayer.FIsActive := false;
end;
Место, где генерируется событие для другого потока, здесь опущено, т.к., насколько я понимаю, суть не в нем.

А это код принудительного завершения:

Код:
.............
  for i := 0 to FLayers.Count - 1 do
  begin
    FLayers.Layer[i].FTerminating := true;
    f := true;
    while f do
    begin
      f := FLayers.Layer[i].IsActive;
      if f then
      begin
        Sleep(100);
        Application.ProcessMessages;
      end;
    end;
    FLayers.Layer[i].FTerminating := false;
  end;
..................
Может быть этот последний кусок и не совсем кошерный, но работать-то он должен по-моему.

Все это в DElphi 7 под WinXP.

Буду рад любым советам умных людей
abb777 вне форума Ответить с цитированием
Старый 19.12.2010, 00:13   #2
abb777
 
Регистрация: 17.12.2010
Сообщений: 6
По умолчанию

Путем последовательных отключений кусков кода выяснил, что проблема, как ни странно, в этой строчке метода Execute:

Код:
    //Synchronize(DoOnStep);
А метод DoOnStep() ничего особенного с виду не представляет:
Код:
procedure TLayerThread.DoOnStep;
begin
  if not FLayer.FTerminating then
    if Assigned(FLayer.FEngine.FOnStep) then
      FLayer.FEngine.FOnStep(FLayer.FEngine, FLayer);
end;
Если этот вызов не комментарить, то при принудительном завершении потоков отладчик показывает, что большинство из них висит на некоем вызове WaitOfSingleObject(), но, как выяснилось, это не тот WaitOfSingleObject(), который я сам использую в методе Execute, а какой-то другой, а CallStack к сожалению на эту тему ничего не показывает.

Это что, баг в Delphi 7 или что???
abb777 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с компиляцией программы Cpluser Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 11 10.12.2010 21:16
Проверка перед закрытием (аналог Паинт) Claster Помощь студентам 0 01.12.2010 17:35
проблема с закрытием формы betirsolt Общие вопросы Delphi 46 03.08.2009 01:00
Проблема в Delphi. Возможно, на потоки. Jean-Esther Помощь студентам 2 21.02.2009 22:32
Проблемма с закрытием MDIChild'ов KirkMETAL Помощь студентам 12 25.11.2007 07:06