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

Вниз

Sleep   Найти похожие ветки 

 
ZV ©   (2006-06-03 23:39) [0]

Можно ли прерывать команду Sleep.Мне нужно во время выполнения команды Sleep проверять выполнение условия


 
DrPass ©   (2006-06-04 00:06) [1]

А как ты думаешь, если ты получишь команду засунуть палец в... ухо, можешь ли ты во время выполнения этой команды поковырять этим пальцем в носу?


 
ZV ©   (2006-06-04 00:11) [2]

Просто и доступно.Молодец.Я так и думал но надеялся на чудо(тут изобретателей хватает). Буду переделывать код


 
Юрий Зотов ©   (2006-06-04 00:39) [3]

> DrPass ©   (04.06.06 00:06) [1]

Одновременно, конечно, не получится, но можно быстро-быстро вытащить палец из ... уха, быстро-быстро ковырнуть им в носу и быстро-быстро засунуть его обратно в ... ухо.

Как бы вытесняющая мультизадачность получается (CPU - он ведь тоже обычно один, но где только не ковыряется, и везде как бы одновременно).

> ZV ©   (03.06.06 23:39)  

Разбиваем нужный интервал ожидания, например, на 100 кусков. Делаем цикл от 1 до 100. Внутрь цикла вставляем Sleep на 1/100 интервала - и в этом же цикле проверяем условие.

Более сложный (но и более лучший) вариант - WaiFor с объектом синхронизации. При наступлении условия освобождаете этот объект - и ожидание прекратилось. То есть, и проверять ничего не потребуется.


 
ZV ©   (2006-06-04 00:45) [4]


> Юрий Зотов ©   (04.06.06 00:39) [3]

Спасибо.Я же знал что здесь изобретателей хватает.

> Более сложный (но и более лучший) вариант - WaiFor с объектом
> синхронизации

вот тут если можно подробней я про это первый раз слышу.


 
Юрий Зотов ©   (2006-06-04 01:18) [5]

См. в справке:
1. Класс TThread, метод Execute.
2. Класс TCriticalSection, методы Enter и Leave.

В главном потоке создаем глобальный объект TCriticalSection и выполняем Enter. Затем создаем второй поток, в его Execute тоже выполняем Enter в ту же критическую секцию. Поскольку она занята, второй поток засыпает и ждет ее освобождения. Главный же поток (то есть, программа) в это время спокойно продолжает работать и когда наступает нужное условие, главный поток выполняет Leave. Критическая секция освобождается, тут же просыпается второй поток, захватывает секцию (Enter), но сразу же выполняет Leave, завершается и самоуничтожается (см. FreeOnTerminate). При этом у него срабатывает событие OnTerminate, на которое можно повесить свой код обработки.

Не знаю Вашей задачи, поэтому не стану утверждать, что эта схема для нее подходит, но подумать о ней, видимо, стоит. Ее преимущества в том, что она:
- дает более точную синхронизацию с наступлением условия;
- не тормозит главный поток (то есть, он нормально обрабатывает сообщения, выполняет отрисовку окон, реагирует на действия юзера и пр.);
- не нагружает CPU лишней работой.


 
ZV ©   (2006-06-04 01:39) [6]

Да!!! Мне бы твои познания. Как то для меня крутовато это сразу освоить,времени нет. Буду изучать


 
Юрий Зотов ©   (2006-06-04 02:27) [7]

> ZV ©   (04.06.06 01:39) [6]

Ничего там особо крутого и сложного нет, просто при программировании надо постоянно помнить, что у нас уже не с один, а с два потока.

Запустите вот этот код и щелкайте по кнопке. А как оно работает - см. в самом коде и в справке.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, SyncObjs, StdCtrls;

type
 TWaitingThread = class(TThread)
 protected
   procedure Execute; override;
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   FWaiting: boolean;
   procedure ConditionHandler(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

var
 CriticalSection: TCriticalSection;

{ TWaitingThread }

procedure TWaitingThread.Execute;
begin
 CriticalSection.Enter; // Поток начал ждать выполнения условия.
 if CriticalSection <> nil then // Чтобы не было AV при закрытии программы.
   CriticalSection.Leave // Поток дождался выполнения условия и завершился
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
 CriticalSection := TCriticalSection.Create // Создали глобальный объект.
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 CriticalSection.Leave; // Если поток ждет, надо дать ему завершиться.
 FreeAndNil(CriticalSection) // Уничтожили глобальный объект.
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 FWaiting := not FWaiting; // Переключаем флажок режима работы.
 if FWaiting then // Запускаем ожидание наступления условия.
   with TWaitingThread.Create(True) do // Создали спящий поток.
   begin
     FreeOnTerminate := True; // Поток самоуничтожится при завершении.
     OnTerminate := ConditionHandler; // Обработчик наступления условия.
     CriticalSection.Enter; // Сразу после запуска поток перейдет в ожидание.
     Color := clRed; // Красный цвет - ожидание запущено.
     Resume // Запустили второй поток и он сразу перешел в ожидание.
   end
 else
   CriticalSection.Leave // Поток просыпается и завершается.
end;

procedure TForm1.ConditionHandler(Sender: TObject);
begin
 Color := clBlue // Синий цвет - условие наступило.
end;

end.


 
Юрий Зотов ©   (2006-06-04 02:30) [8]

Забыл добавить: первое нажатие кнопки запускает ожидание выполнения условия, второе нажатие этой же кнопки означает, что условие наступило.



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

Форум: "Начинающим";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.011 c
2-1149493542
allrussia
2006-06-05 11:45
2006.06.25
Организовать в проекте скачивание файлов по принципу работы Reget


8-1137680930
misha_gr
2006-01-19 17:28
2006.06.25
Странная проблема с DsPack


1-1147960956
Alex35
2006-05-18 18:02
2006.06.25
Какие сделать демки?


15-1149173491
DillerXX
2006-06-01 18:51
2006.06.25
GetMemory в DLL


2-1149691471
Chelovek
2006-06-07 18:44
2006.06.25
Поток долго завершается.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский