Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.07;
Скачать: CL | DM;

Вниз

WaitForMultipleObjects   Найти похожие ветки 

 
Stas_Kalishenko   (2006-02-15 18:27) [0]

Помогите! WaitForMultipleObjects возвращает -1 (минус единицу). Что это означает?
Вот как вызываю:
ncount := WaitForMultipleObjects(t_count,@lpHandles,False,INFINITE);

где t_count=10,
ncount - тип integer


 
begin...end ©   (2006-02-15 18:35) [1]

Это означает WAIT_FAILED (ошибка). Чтобы выяснить, какая именно, вызовите GetLastError.


 
Stas_Kalishenko   (2006-02-15 18:47) [2]

Код ошибки - 6: Неверный дескриптор. Где копать причину сбоя?


 
kaZaNoVa ©   (2006-02-15 18:56) [3]

Stas_Kalishenko   (15.02.06 18:47) [2]

> где t_count=10,

почему это он равен 10-ти?)


 
begin...end ©   (2006-02-15 19:34) [4]

> Stas_Kalishenko   (15.02.06 18:47) [2]
> Где копать причину сбоя?

Вероятно, в содержимом массива дескрипторов, адрес которого передаётся в WaitForMultipleObjects. Код его заполнения можно увидеть?


 
Marser ©   (2006-02-15 22:42) [5]

> [1] begin...end ©   (15.02.06 18:35)
> Это означает WAIT_FAILED (ошибка).

WAIT_FAILED  = DWORD($FFFFFFFF);
?
Это не WAIT_FAILED.


 
GuAV ©   (2006-02-16 02:03) [6]


>?
> Это не WAIT_FAILED.

Это WAIT_FAILED.

Просто оно интепреретировано как знаковое, т.к.

> ncount := WaitForMultipleObjects


> ncount - тип integer


 
Marser ©   (2006-02-16 02:07) [7]

> [6] GuAV ©   (16.02.06 02:03)
>
> >?
> > Это не WAIT_FAILED.
>
> Это WAIT_FAILED.
>
> Просто оно интепреретировано как знаковое, т.к.
>
> > ncount := WaitForMultipleObjects
>
>
> > ncount - тип integer

Действительно... Беру свой вопрос назад.


 
Stas_Kalishenko   (2006-02-16 09:14) [8]

Дело в том, что создаю потоки и жду, когда хотя бы один из них завершится, далее создаю следующий и жду снова, когда один из созданных завершится. Все идет вроде нормально до какого-то момента, а потом -  access violation. Начал проверять отработку WaitForMultipleObjects, смотрю возвращает -1. Вот сам код цикла вызова потоков.

var Thr: TSaldoThread;
   lpHandles: array [0..t_count - 1] of Cardinal;
   ADOQuery: TADOQuery;
   i, ncount: integer;

...

for i := 0 to ADOQuery.RecordCount - 1 do
    begin
       if i < t_count then
       begin
         Thr := TSaldoThread.Create(False,
                                    Form1.DateTimePicker1.DateTime,
                                    Form1.DateTimePicker2.DateTime,
                                    ADOQuery.FieldByName("date_open").AsDateTime,
                                    ADOQuery.FieldByName("acc").AsString,
                                    ADOQuery.FieldByName("notice").AsString);
         lpHandles[i] := Thr.Handle;
         Thr.FreeOnTerminate := True;
       end
       else
       begin
         ncount := WaitForMultipleObjects(t_count,@lpHandles,False,INFINITE);

         if ncount = -1 then
           RaiseLastOSError
         else
         begin
           Thr := TSaldoThread.Create(False,
                                      Form1.DateTimePicker1.DateTime,
                                      Form1.DateTimePicker2.DateTime,
                                      ADOQuery.FieldByName("date_open").AsDateTime,
                                      ADOQuery.FieldByName("acc").AsString,
                                      ADOQuery.FieldByName("notice").AsString);
           lpHandles[ncount] := Thr.Handle;
           Thr.FreeOnTerminate := True;
         end;
       end;
       ADOQuery.Next;
    end;

>>почему это он равен 10-ти?)

t_count у меня константа, равная 10 - ограничение количества запускаемых потоков. Но это не столь важно, она может быть какой угодно (в разумных пределах).


 
Stas_Kalishenko   (2006-02-16 09:22) [9]

Поправка к предыдущему посту: "создаю 10 потоков и жду, когда хотя бы один из них завершится...".

>>Вероятно, в содержимом массива дескрипторов, адрес которого передаётся в WaitForMultipleObjects.

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


 
Stas_Kalishenko   (2006-02-16 09:27) [10]

Обнаружил такую дурацкую закономерность: если ставлю ограничение кол-ва потоков 10, то все выполняется до 90% от общего кол-ва потоков, т.е. если кол-во потоков 150, то выполняется из них примерно 135, а потом access violation (все это, конечно, без обработки ncount=-1, т.е. убрав  if ncount = -1 then  RaiseLastOSError). Если ставлю ограничение 5 потоков - вылетает примерно на 95%. А вот если ставлю ограничение на 2 потока, то все проходит гладко.


 
Digitman ©   (2006-02-16 09:30) [11]


> Thr.FreeOnTerminate := True


Убери автоуничтожение.
Когда тред просигналит о своем завершении, уничтожай его явно.


 
Stas_Kalishenko   (2006-02-16 09:36) [12]

А как именно сигналить о завершении? Можно пример?


 
begin...end ©   (2006-02-16 09:47) [13]

> Stas_Kalishenko   (16.02.06 09:14) [8]

Установка FreeOnTerminate в True означает, что сразу после выхода из поточной функции будет вызван Destroy, т.е. объект потока будет уничтожен, и (что главное) -- будет закрыт дескриптор потока. После этого обращение к этому дескриптору будет давать ошибку.


 
Stas_Kalishenko   (2006-02-16 09:52) [14]

>>Установка FreeOnTerminate в True означает, что сразу после выхода из поточной функции будет вызван Destroy, т.е. объект потока будет уничтожен, и (что главное) -- будет закрыт дескриптор потока. После этого обращение к этому дескриптору будет давать ошибку.

Это я уже понял. Только как из созданного потока сигнализировать о своем завершении и обрабатывать это, пока не понял.


 
begin...end ©   (2006-02-16 09:56) [15]

> Stas_Kalishenko   (16.02.06 09:36) [12]

О завершении функции потока Вам просигналит WaitForMultipleObjects. После этого можно будет самостоятельно разрушить объект и закрыть хэндл, вызвав Free нужного экземпляра. Только указатели на экземпляры нужно сохранять.


 
Digitman ©   (2006-02-16 09:59) [16]

WaitForMultipleObjects-функция у тебя как раз и занята ничем иным кроме как ожиданием тех самых сигналов, так что ничего нового изобретать не нужно.

var
lpHandles: array [0..t_count - 1] of Cardinal;
Threads: array [0..t_count - 1] of TThread;

ncount := WaitForMultipleObjects(t_count,@lpHandles,False,INFINITE);
Win32Check(ncount <> WAIT_FAILED);

//сначала разрушаем объект
Threads[ncount].Free;

//тут же воссоздаем его
Threads[ncount] := TSaldoThread.Create(True, //CREATE_SUSPENDED
                                     Form1.DateTimePicker1.DateTime,
                                     Form1.DateTimePicker2.DateTime,
                                     ADOQuery.FieldByName("date_open").AsDateTime,
                                     ADOQuery.FieldByName("acc").AsString,
                                     ADOQuery.FieldByName("notice").AsString)
with Threads[ncount] do begin
lpHandles[ncount] := Handle; //зафиксировали хэндл
Resume; //разбудили поток
end;


 
Stas_Kalishenko   (2006-02-16 10:14) [17]

Ок. Спасибо.



Страницы: 1 вся ветка

Текущий архив: 2006.05.07;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.041 c
3-1142264205
Ega23
2006-03-13 18:36
2006.05.07
Размер таблицы в памяти


15-1144737138
Тульский
2006-04-11 10:32
2006.05.07
Лимон на подоконнике


10-1118573883
SerJ23
2005-06-12 14:58
2006.05.07
определение номера абзаца


4-1140205287
Eraser
2006-02-17 22:41
2006.05.07
ISecurityInformation и Aclui.pas


2-1144954625
Couter Terranist
2006-04-13 22:57
2006.05.07
Помогите с SQL-запросом