Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Вниз

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 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.012 c
2-1145266949
jenya_rus
2006-04-17 13:42
2006.05.07
Работа с FileList...


15-1144856995
ArtemESC
2006-04-12 19:49
2006.05.07
Настольгия...


15-1144734860
DelphiN!
2006-04-11 09:54
2006.05.07
Книга по Visual Studio 2005


3-1142576870
SLP
2006-03-17 09:27
2006.05.07
Отмена предупреждающего окна Excel


3-1142481768
Ezorcist
2006-03-16 07:02
2006.05.07
BDE или ADO? Помогите определиться.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский