как заставить программу ждать завершения потока? если я пишу: Code: Program prog; var i:integer; thr,id:array [1..300] of Cardinal; Procedure proc; begin MessageBox(0,'Yo!','',mb_ok); end; begin for i := 1 to 300 do begin thr[i]:=CreateThread(nil,0,@proc,nil,0,id[i]); end; end. сообщения появляются, тутже исчезают и прога отсатавливается. если вот так: Code: Program prog; var i:integer; thr,id:array [1..300] of Cardinal; Procedure proc; begin MessageBox(0,'Yo!','',mb_ok); end; begin for i := 1 to 300 do begin thr[i]:=CreateThread(nil,0,@proc,nil,0,id[i]); end; sleep(5000); end. сообщения появляются на 5 сек и прога завершается. вопрос как заставить прогу ждать завершения потоков?
ставишь счетчик, при завершении каждого потока увеличиваешь его на единицу, в основном потоке ждешь, когда этот счетчик будет равен числу потоков. Не забыть про синхронизацию, примерно так Code: Program prog; var i:integer; thr,id:array [1..300] of Cardinal; fl:integer;//счетчик для контроля завершения потоков cs:TRTLCriticalSection ;//крит секция Procedure proc; begin MessageBox(0,'Yo!','',mb_ok); EnterCriticalSection(cs); inc(fl); LeaveCriticalSection(cs); end; begin InitializeCriticalSection(cs); for i := 1 to 300 do begin thr[i]:=CreateThread(nil,0,@proc,nil,0,id[i]); end; fl:=0; repeat sleep(10); until fl=length(thr); end.
for (i = 0; i < threadsnum; i++) WaitForSingleObject(threads, INFINITE); WaitForMultipleObjects не может принять более 64 объектов.
Псевдокодом можно это описать так: Code: var N - глобальная переменная // наша функция которая что-то делает там function THProc (p:pointer):dword;stdcall; begin трам парам // при завершении работы потока атомарно уменьшим кол-во активных потоков InterlockedDecriment( N ); end; N := 0; // пока у нас 0 активных потоков for x := to Z do // цикл запуска Z потоков begin h := CreateThread(**** THProc ***) // запускаем поток if (h <> 0) then // если запустился begin CloseHandle(h); // закрываем хендл потока чтобы не мешался InterlockedIncriment( N ); // атомарно увеличиваем кол-во активных потоков end; end; // гоняем цикл пока есть активные потоки while (N <> 0) do begin Sleep(100); // делаем паузу 1/10 секунду чтобы проц не подвешивался end; Код такой будет работать идеально и пофигу сколько потоков будет использоваться
И так Code: var N : Integer; глобальная переменная var event : THande; // наша функция которая что-то делает там function THProc (p:pointer):dword;stdcall; begin трам парам // при завершении работы потока атомарно уменьшим кол-во активных потоков if InterlockedDecriment( N ) = 0 then SetEvent(event); end; ... event := CreateEvent(nil, true, false, nil); N := 0; // пока у нас 0 активных потоков for x := 1 to Z do // цикл запуска Z потоков begin h := BeginThread(nil, 0, @THProc, nil, CREATE_SUSPENDED, dummy); //запускаем поток if (h <> 0) then // если запустился begin InterlockedIncriment( N ); // атомарно увеличиваем кол-во активных потоков ResumeThread(h); CloseHandle(h); // закрываем хендл потока чтобы не мешался end; end; // гоняем цикл пока есть активные потоки if WaitForSingleObject(event, INFINITE) <> WAIT_ABANDONED then CloseHandle(event);
Лолват? "Для чисел лучше забыть про interlocked" - типа я вот так вот писал? "еще и на генериках..." и? дженерики медленные чтоли? вроде тут ошибочное представление о природе дженериков..это же не variant, и не TValue и не любой другой "универсальный тип" а именно дженерики.