Форум: "Начинающим";
Текущий архив: 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