Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];

Вниз

Как усыпить поток.   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.016 c
15-1141060551
whisky
2006-02-27 20:15
2006.03.19
Поиск компонентов


3-1138199915
Kot_
2006-01-25 17:38
2006.03.19
Пропадают записи.


10-1115290907
Santyago
2005-05-05 15:01
2006.03.19
Как в Excel документе можно определить конец файла


9-1126538054
WonderfulDay
2005-09-12 19:14
2006.03.19
запаковать растры


1-1140185224
KyRo
2006-02-17 17:07
2006.03.19
Почему не стартует нить ??





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский