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

Вниз

Как освободить спящий поток?   Найти похожие ветки 

 
Aleksandr ©   (2003-08-15 14:41) [0]

В программе работает поток типа Шедулера. То есть его выполнение состоит из вычисления оставшегося времени до события, после чего он на это время выполняет Sleep, а по пробудке выполняет событие:

procedure TSheduler.Execute;
begin
repeat
if InitWaitTime then begin // если запланировано событие, установить время ожидания
Sleep(FWaitTime); // спать время ожидания
DoCurrentEvent // выполнить событие
end
else
Sleep(FIdleTime) // просто слегка отдохнуть, чтобы не загружать
until Terminated //FreeOnTerminate=false
end;

Код не самый удачный, но он рожден унификацией одного модуля для нескольких программ. Отсюда же вытекает и проблема - если программу, в которой работает шедулер, закрыть, то на вызове Free спящего потока она просто повесится до его пробуждения. Вызов Terminate и Resume перед освобождением ничего не дает.


 
Spawn ©   (2003-08-15 14:43) [1]

А ты не используй Sleep, а юзай GetTickCount с постоянной проверкой на состояние потока.


 
vuk ©   (2003-08-15 14:46) [2]

А почему Sleep? Может лучше WaitForSingleObject с таймаутом? При этом ждеть Event-а, и по наступлении этого Event-а завершать выполнение потока?


 
vuk ©   (2003-08-15 14:48) [3]

Хотя, если шедулер и WinXP, то можно WaitableTimer использовать...


 
Aleksandr ©   (2003-08-15 14:51) [4]

Конечно, лучше WaitForSingleObject. Я бы так и сделал, но, на данный момент, некоторые технические соображения требуют попытаться решить проблему без переделок модуля с этим недорожденным (то есть нет исходного кода).


 
Serginio784   (2003-08-15 15:02) [5]

SleepEx


 
Camus ©   (2003-08-15 15:14) [6]

Как разбудить поток немедленно и без правки исходника модуля, я не нашел. Но при закрытии программы можно дождаться, пока он сам проснется, причем без эффекта подвисания.

1. Вариант с API - что-то типа этого:
CanClose := GetExitCodeThread(...) <> STILL_ACTIVE;

2. Чисто VCL"ный вариант - при создании потока назначить ему OnTerminate, в обработчике выставлять флаг, а CanClose выдавать по этому флагу.


 
Aleksandr ©   (2003-08-15 15:26) [7]

Serginio784 :
Как я уже написал, код шедулера не поддается изменениям. И, кстати, насколько я понимаю, эта функция может выходить только по ошибкам ввода/вывода?

Camus :
Ну что же... Дождаться без эффекта повисания - тоже вариант :). Особенно, если событие запланировано на через неделю после запуска программы :)))


 
Serginio412   (2003-08-15 15:29) [8]

>Aleksandr © (15.08.03 15:26) [7]
APC


 
pasha_golub ©   (2003-08-15 16:12) [9]

Можно очень грубо покилять процесс с помощью АПИ, ИМХО


 
pasha_golub ©   (2003-08-15 16:14) [10]

TerminateThread(...) как раз для аварийного останова


 
Aleksandr ©   (2003-08-15 16:43) [11]

О, вот это в самый раз. Главное, сам знал, но по тупости забыл. Спасибо.


 
vuk ©   (2003-08-15 17:06) [12]

Вы, однако, поосторожнее с TerminateThread, а то можно утечек памяти и ресурсов нахвататься...


 
Aleksandr ©   (2003-08-15 17:29) [13]

Ну да... можно, насколько я понимаю, если у потока есть объекты-свойства, освобождаемые в дестракторе. А без них вроде ничего.


 
vuk ©   (2003-08-15 17:42) [14]

Строки опять же...



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

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

Наверх




Память: 0.49 MB
Время: 0.019 c
4-1726
hawkins
2003-06-30 12:21
2003.09.01
как удалить несколько символов из текстового файла


1-1469
Влад Штогрин
2003-08-18 14:22
2003.09.01
Определение в системе динамического отладчика


1-1453
kuchumovkv
2003-08-18 18:05
2003.09.01
Планировщик в Delphi


1-1368
Franzy
2003-08-17 15:03
2003.09.01
Глюк со spinedit.


6-1524
Basil
2003-06-26 14:20
2003.09.01
закачка по FTP