Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.57 MB
Время: 0.08 c
2-1141152193
tyo
2006-02-28 21:43
2006.03.19
мелкий/крупный шрифт


15-1140711048
Knight
2006-02-23 19:10
2006.03.19
Кто встречался с таким глюком при выводе 3D?


8-1129021210
Ajax
2005-10-11 13:00
2006.03.19
Захват звукового вывода


15-1140874980
WondeRu
2006-02-25 16:43
2006.03.19
Как организовать связь между приложением и ISAPI (CGI) модулем?


15-1140601946
Compton's G
2006-02-22 12:52
2006.03.19
Сетевой эмулятор