![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как усыпить поток. [D7, WinXP]
Kolan © (2006-02-06 21:50:00)Здравствуйте,
Много раз слышал при обсуждении работы с потоками
"если то-то то поток засыпает, если еще что-то то просыпается..."
А как это. Можно пример усыпления.
Я просто проверяю какое-нибудь условие и если потоку делать нечего делаю например Sleep(1). А иначе загрузка процессора на 97% - 99%
Fay (2006-02-07 15:03:00) [61]Pocket M - это кто?
Kolan (2006-02-07 15:00:00) [62]формирует
Не понял, что это занчит
Но изменяют их главный и доп поток...
Но повторюсь что все проверял на больших покетах м все работало... 100%
"кольцевой буфер"
циклический массив
Да уж оба слова перепутал...
:)
Digitman (2006-02-07 14:56:00) [63]
> Вот они. FReadIndex как бы догоняет FWriteIndex если они
> сравнялись, то жду пока еще добавят байты
Ты, вероятно, хотел сказать "кольцевой буфер" ..
Кстати, а какой поток формирует значения FReadIndex и FWriteIndex ?
Kolan (2006-02-07 14:44:00) [64]Да этопросто массив фиксированный длинны. И два индекса по которому читаю и по которуму добовляю элементы.
FWriteIndex <> FReadIndex
Вот они. FReadIndex как бы догоняет FWriteIndex если они сравнялись, то жду пока еще добавят байты...
Как только пакет найден я его передаю, а индексы обнуляю(начинаю заполнять массив занаво).
Тут все работает проверял....
Digitman (2006-02-07 14:41:00) [65]
> циклический массив
Это еще что за зверь ?!
Kolan (2006-02-07 14:37:00) [66]Поясню суть работы потока.
Он ананлизирует циклический массив на предмет нахождения пакета данных. Добавляет элементы в цикл массив другой поток...
Если нашел пакет то
Synchronize(MakeAndSendPackage);
Спать должен если нашел пакет или дошел до конца цикл массива и ждет когда добавят продолжение.
Kolan (2006-02-07 14:32:00) [67]Fay © (07.02.06 14:22) [21]
Просто с ходу не получилось...
Вот что получилось.
FreeOnTerminate := True;
while not Terminated do
begin
WaitForSingleObject(FEvent, INFINITE);
if (FState <> sIdle) and (FWriteIndex <> FReadIndex) then
begin
{Packge parsing}
begin
ResetEvent(FEvent);
end;
end;
И еще две процедуры
procedure TPackageExtractThread.AddArray(Arr: array of Byte);
var
I, J: Longint;
begin
{Adding}
SetEvent(FEvent);
end;
procedure TPackageExtractThread.MakeAndSendPackage;
var
I, J: Longint;
Answer: array of Byte;
begin
ResetEvent(FEvent);
{Converting...}
FState := sIdle;
FReadIndex := 0;
FWriteIndex := 0;
FPackageReadyEvent(Self, Answer);
end;
Почемуто затыкается на 3 вызове Wait функции. Немогу отладить...
ДоMakeAndSendPackage
дело не доходит..
Fay © (07.02.06 14:22) [21]
Вот я и подумал, что может повторный вызов SetEvent причина...
Digitman (2006-02-07 14:23:00) [68]
> Если я уже сделал SetEvent и сделаю ео повторно - что будет?
Тоже самое что установка в True булевой переменной, уже содержащей на этот момент True.
> посмотреть состояние Event'а можно как-нибудб(для отладки).
Не нужно его "смотреть".
Просто поставь брейкпойнт на следующей строчке за вызовом Wait-ф-ции и поймай его.
Fay (2006-02-07 14:22:00) [69]> и сделаю ео повторно - что будет?
Event будет в сигнальном состоянии. А что ещё может быть? 8)
Kolan (2006-02-07 14:19:00) [70]Вопрос такой: Если я уже сделал
SetEventи сделаю ео повторно - что будет?
И еще а посмотреть состояниеEvent'аможно как-нибудб(для отладки).
Fay (2006-02-07 14:10:00) [71]> И пока оно не наступит поток будет спать?
или пока event не сдохнет
Kolan (2006-02-07 14:05:00) [72]О. Шас попробую...
Digitman (2006-02-07 14:03:00) [73]
> как установить его в положение "случилось/неслучилось"?
SetEvent() = "случилось
> я жду это событие с INFINITE Таймаутом. И пока оно не наступит
> поток будет спать? Так?
Да.
Fay (2006-02-07 14:03:00) [74]SetEvent/ResetEvent
wal (2006-02-07 14:03:00) [75]
> Те как установить его в положение "случилось/неслучилось"?
Set/Reset/PulseEvent
> И пока оно не наступит поток будет спать? Так?
Так
Kolan (2006-02-07 13:48:00) [76]Допустим я создам
FEvent := CreateEvent(nil, False, False, nil);
И буду ждать егоWaitForSingleObject
Вопрос: а как управлятьFEvent. Те как установить его в положение "случилось/неслучилось"?
И дальше я жду это событие сINFINITEТаймаутом. И пока оно не наступит поток будет спать? Так?
Kolan (2006-02-07 13:35:00) [77]Ага нашел... Читаю :)
Digitman (2006-02-07 13:27:00) [78]
> получится что поток постоянно просыпается и завсыпает(я
> думаю, что это гораздо хуже будет).
В этом-то как раз нет ничего страшного.
Но вcе те 2 мс, пока поток спит на строчке Sleep(2), он не способен ни на что реагировать, вплоть до своего "пробуждения"... Если это не критично, то логика вида
while not Terminated do
if Нечего_делать then
sleep(..)
else
делать_дело
в принципе имеет право на жизнь.
Хотя гораздо резонней будет подход, когда поток "спит" и "слышит" сигналы "пробуждения" (см. Wait-ф-ции)
Kolan (2006-02-07 13:20:00) [79]"спать"
Те надо сделать Suspend?
Вот часть моей программы:
procedure TPackageExtractThread.Execute;
var
State: TState;
CurrentIndex: Longint;
BufferEnd: Longint;
begin
FreeOnTerminate := True;
while not Terminated do
begin
if (FState <> sIdle) and (FWriteIndex <> FReadIndex) then
begin
{Working}
end
else
begin
Sleep(2);
end;
end;
end;
Если я ВместоSleepбуду вызоватьSuspend, тогода при частой смене условия(FState <> sIdle) and (FWriteIndex <> FReadIndex)(а оно так и происходит когда идет работа), получится что поток постоянно просыпается и завсыпает(я думаю, что это гораздо хуже будет).
Поэтому я хочу наложить условиеЕсли ничего не делал 1мин то засапаю...
wal (2006-02-07 13:14:00) [80]Можно в качестве такого "флага" использовать какой-либо объект синхронизации, например крит.секцию, только продумать все надо, чтобы дед-локов не натворить.