Показать сообщение отдельно
  #9  
Старый 18.12.2013, 03:07
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Чтобы цикл ожидания потоков не напрягал процессор почём зря, нужно в этом цикле сделать небольшую задержку:
Код:
repeat
  Sleep(100); // Теоретически достаточно даже Sleep(0)
  enp := True;
  for it := 0 to itc - 1 do
    enp := enp and ther[it].Finished;
until enp;
Кроме того вместо самопального цикла ожидания можно использовать стандартную WaitForMultipleObjects которая умеет ожидать до 64 объектов синхронизации одновременно.

И да, при "FreeOnTerminate:=True" неправомерно выполнять обращения к объекту этого потока из другого потока, так как объект к этому времени уже может быть разрушен (вследствие завершения выполнения потока). Если необходимо обращаться к объекту потока из другого потока нужно делать "FreeOnTerminate:=False", но тогда и самостоятельно разрушать объекты потоков (или возложить эту миссию на объект класса TObjectList из модуля Contnrs).
Если же делать "FreeOnTerminate:=True", то так как к такому объекту потока, нельзя обращаться из другого потока - поток должен сам как-то оповестить о своём завершении. Например можно объявить глобальную переменную-счётчик потоков. При создании нового потока увеличивать эту переменную, а каждый поток перед своим завершением должен уменьшать эту переменную (обязательно через Synchronize или InterlockedDecrement), тогда в цикле достаточно просто проверять не достигло ли значение этой переменной нуля:
Код:
var
  NumThr: Integer = 0; // Это будет счётчик запущенных потоков
.....
begin
.....
  for it := 1 to itc do
  begin
    ther[it-1] := Rasch.Create(True);
    Inc(NumThr); // Увеличиваем количество созданных потоков на единицу
    ther[it-1].FreeOnTerminate := True; // Авторазрушаемый объект потока
.....
    ther[it-1].Resume;
  end;

  while NumThr > 0 do Sleep(100); // Ожидаем завершения всех потоков
.....
end;
.....

.....
procedure Rasch.Execute;
begin
  proc(kss, ke);
  InterlockedDecrement(NumThr); // Перед завершением потока уменьшаем количество
                                // запущенных потоков, а объект потока сам разрушится
                                // благодаря FreeOnTerminate := True
end;
Ответить с цитированием