Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.06.25;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.028 c
3-1146121628
Ильичев С.А.
2006-04-27 11:07
2006.06.25
SELECT после INSERT


2-1149597376
fast2
2006-06-06 16:36
2006.06.25
Как добавить строку вStringGrid e?


2-1149588259
D@Nger
2006-06-06 14:04
2006.06.25
Ошибка при поиске методом Locate


3-1146214759
alsov
2006-04-28 12:59
2006.06.25
Надежность FireBird Embedded


2-1149605973
redlord
2006-06-06 18:59
2006.06.25
как передать чужому окну (по недел) код нажатой клавиши