Текущий архив: 2006.03.19;
Скачать: CL | DM;
Вниз
Как усыпить поток. Найти похожие ветки
← →
Kolan © (2006-02-06 21:50) [0]Здравствуйте,
Много раз слышал при обсуждении работы с потоками
"если то-то то поток засыпает, если еще что-то то просыпается..."
А как это. Можно пример усыпления.
Я просто проверяю какое-нибудь условие и если потоку делать нечего делаю например Sleep(1). А иначе загрузка процессора на 97% - 99%
← →
Eraser © (2006-02-06 22:41) [1]
> Kolan © (06.02.06 21:50)
чаще всего под "усыплением" потока подразумевают ожидание в этом потоке какого-либо объекта синхронизации, какай-либо ф-ей, предназначеной для этого, например WaitForSingleObject или EnterCriticalSection.
Sleep это всё таки немного иное...
← →
Kolan © (2006-02-06 23:54) [2]Понятно.
Я димал мож есть функция какая. Что-то вродеThread.Sleep
иThread.Awake
...
← →
Gero © (2006-02-07 00:01) [3]> Kolan © (06.02.06 23:54)
Suspend, Resume
← →
evvcom © (2006-02-07 11:36) [4]
> Я димал мож есть функция какая.
Думал? Есть, но не функция, а метод, если речь идет о TThread. См. [3]
← →
Kolan © (2006-02-07 12:59) [5]Интересует вот что: Допустим поток будет выполнять работу если какой-то флаг = True.
В случае если прошло какое-то время и флаг всевремя был равен False( Те поток бездействовал), поток засыпал бы....
← →
Digitman © (2006-02-07 13:05) [6]
> В случае если прошло какое-то время и флаг всевремя был
> равен False( Те поток бездействовал), поток засыпал бы
Вряд ли такая затея чем-то оправдана
← →
Kolan © (2006-02-07 13:09) [7]Вряд ли такая затея чем-то оправдана
Наверно потому что...
http://delphimaster.net/view/4-1138784983/
Digitman © (01.02.06 12:41) [3]
Ведь создание и старт трэда сродни пуску холодного автодвигателя !
Да?
Я просто попробовать такое сделать хотел...
← →
Digitman © (2006-02-07 13:09) [8]Если потоку нечего делать, лучшее чем он может заняться в это время - "спать".
"Пустая" циклическая же проверка же флага (если имеется ввиду флаг как результат user-time-вычисления некоего условия) ничем не оправдана.
← →
Digitman © (2006-02-07 13:13) [9]
> Наверно потому что
> ... автодвигателя
Нет, вовсе не поэтому.
← →
wal © (2006-02-07 13:14) [10]Можно в качестве такого "флага" использовать какой-либо объект синхронизации, например крит.секцию, только продумать все надо, чтобы дед-локов не натворить.
← →
Kolan © (2006-02-07 13:20) [11]"спать"
Те надо сделать 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мин то засапаю...
← →
Digitman © (2006-02-07 13:27) [12]
> получится что поток постоянно просыпается и завсыпает(я
> думаю, что это гораздо хуже будет).
В этом-то как раз нет ничего страшного.
Но вcе те 2 мс, пока поток спит на строчке Sleep(2), он не способен ни на что реагировать, вплоть до своего "пробуждения"... Если это не критично, то логика вида
while not Terminated do
if Нечего_делать then
sleep(..)
else
делать_дело
в принципе имеет право на жизнь.
Хотя гораздо резонней будет подход, когда поток "спит" и "слышит" сигналы "пробуждения" (см. Wait-ф-ции)
← →
Kolan © (2006-02-07 13:35) [13]Ага нашел... Читаю :)
← →
Kolan © (2006-02-07 13:48) [14]Допустим я создам
FEvent := CreateEvent(nil, False, False, nil);
И буду ждать егоWaitForSingleObject
Вопрос: а как управлятьFEvent
. Те как установить его в положение "случилось/неслучилось"?
И дальше я жду это событие сINFINITE
Таймаутом. И пока оно не наступит поток будет спать? Так?
← →
wal © (2006-02-07 14:03) [15]
> Те как установить его в положение "случилось/неслучилось"?
Set/Reset/PulseEvent
> И пока оно не наступит поток будет спать? Так?
Так
← →
Fay © (2006-02-07 14:03) [16]SetEvent/ResetEvent
← →
Digitman © (2006-02-07 14:03) [17]
> как установить его в положение "случилось/неслучилось"?
SetEvent() = "случилось
> я жду это событие с INFINITE Таймаутом. И пока оно не наступит
> поток будет спать? Так?
Да.
← →
Kolan © (2006-02-07 14:05) [18]О. Шас попробую...
← →
Fay © (2006-02-07 14:10) [19]> И пока оно не наступит поток будет спать?
или пока event не сдохнет
← →
Kolan © (2006-02-07 14:19) [20]Вопрос такой: Если я уже сделал
SetEvent
и сделаю ео повторно - что будет?
И еще а посмотреть состояниеEvent"а
можно как-нибудб(для отладки).
← →
Fay © (2006-02-07 14:22) [21]> и сделаю ео повторно - что будет?
Event будет в сигнальном состоянии. А что ещё может быть? 8)
← →
Digitman © (2006-02-07 14:23) [22]
> Если я уже сделал SetEvent и сделаю ео повторно - что будет?
Тоже самое что установка в True булевой переменной, уже содержащей на этот момент True.
> посмотреть состояние Event"а можно как-нибудб(для отладки).
Не нужно его "смотреть".
Просто поставь брейкпойнт на следующей строчке за вызовом Wait-ф-ции и поймай его.
← →
Kolan © (2006-02-07 14:32) [23]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 причина...
← →
Kolan © (2006-02-07 14:37) [24]Поясню суть работы потока.
Он ананлизирует циклический массив на предмет нахождения пакета данных. Добавляет элементы в цикл массив другой поток...
Если нашел пакет тоSynchronize(MakeAndSendPackage);
Спать должен если нашел пакет или дошел до конца цикл массива и ждет когда добавят продолжение.
← →
Digitman © (2006-02-07 14:41) [25]
> циклический массив
Это еще что за зверь ?!
← →
Kolan © (2006-02-07 14:44) [26]Да этопросто массив фиксированный длинны. И два индекса по которому читаю и по которуму добовляю элементы.
FWriteIndex <> FReadIndex
Вот они. FReadIndex как бы догоняет FWriteIndex если они сравнялись, то жду пока еще добавят байты...
Как только пакет найден я его передаю, а индексы обнуляю(начинаю заполнять массив занаво).
Тут все работает проверял....
← →
Digitman © (2006-02-07 14:56) [27]
> Вот они. FReadIndex как бы догоняет FWriteIndex если они
> сравнялись, то жду пока еще добавят байты
Ты, вероятно, хотел сказать "кольцевой буфер" ..
Кстати, а какой поток формирует значения FReadIndex и FWriteIndex ?
← →
Kolan © (2006-02-07 15:00) [28]формирует
Не понял, что это занчит
Но изменяют их главный и доп поток...
Но повторюсь что все проверял на больших покетах м все работало... 100%
"кольцевой буфер"
циклический массив
Да уж оба слова перепутал...
:)
← →
Fay © (2006-02-07 15:03) [29]Pocket M - это кто?
← →
Kolan © (2006-02-07 15:06) [30]Извените, отвечу позже :)
← →
evvcom © (2006-02-07 15:07) [31]
> Но изменяют их главный и доп поток...
Что-то в твоем коде синхронизации доступа к ним не видно... :( Очень подозрительна фраза "все работает"
← →
evvcom © (2006-02-07 15:09) [32]
> FReadIndex как бы догоняет FWriteIndex если они сравнялись,
> то жду пока еще добавят байты
А если Write на круг обогнал Read?
← →
Digitman © (2006-02-07 15:33) [33]
> Kolan © (07.02.06 15:00) [28]
Да уж .. где синхронизация-то ? доступа к этим данным ?
← →
Kolan © (2006-02-07 16:13) [34]
Да уж .. где синхронизация-то ? доступа к этим данным ?
Нету
Я думая она ненужна... Ведь записываю и читаю всегда по разным индексам...
Может я и неправ.
Вообщето она была, но я убрал ее...А если Write на круг обогнал Read?
Нет такое невозможно... Если по идее до конца массива они не дойдут( если дойдут массив увеличу...)
← →
Digitman © (2006-02-07 16:16) [35]
> Может я и неправ
с учетом
> изменяют их главный и доп поток
оч даже неправ !
← →
evvcom © (2006-02-07 16:28) [36]
> Ведь записываю и читаю всегда по разным индексам
Ты сами переменные читаешь и пишешь в разных потоках, уже это надо синхронизировать.
← →
Kolan © (2006-02-07 16:32) [37]Доп поток изменяет только индекс чтения. Гл поток изменяет индекс записи.
Причем если состояние Idle(те доп поток не работает) обнуляет индексы.
Когда поток нашел покет, он вызовет процедуру передач и пакета и обнулит индексы. Не пойму где они пересекутся.
Или если один поток пишет по индексу A а второй по индексу B одного и тогоже массива(причем точно индексы разные) - будет ошибка?
Скажите - это может повлиять на правильность работы с Event. Те из - за чего межет засыпать...
← →
Digitman © (2006-02-07 16:36) [38]
> Когда поток нашел покет, он вызовет процедуру передач и
> пакета и обнулит индексы. Не пойму где они пересекутся
> Доп поток изменяет только индекс чтения
"Как тебя понимать, Саид ?" (с)
← →
Kolan © (2006-02-07 16:40) [39]Kolan © (07.02.06 14:19) [20]
Вопрос такой: Если я уже сделал SetEvent и сделаю ео повторно - что будет?
Я это не просто так спрашивал. Я сначала все позашишал кр. секциями...
Возникала сит когда я дважды делалRelease
и потомAcquire
уже не вызывался. Как проверить тек сост кр. секции я ненашел...
Поэтому переделал без кс.
А что будет ошибка если один поток сделаетFWriteIndex := J;
А второй в этоже время проверитif (FState <> sIdle) and (FWriteIndex <> FReadIndex) then
?
← →
Digitman © (2006-02-07 16:42) [40]
> А что будет ошибка если один поток сделает
> FWriteIndex := J;
> А второй в этоже время проверит
> if (FState <> sIdle) and (FWriteIndex <> FReadIndex) then
> ?
Бардак будет.
Страницы: 1 2 3 вся ветка
Текущий архив: 2006.03.19;
Скачать: CL | DM;
Память: 0.56 MB
Время: 0.014 c