Форум: "WinAPI";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
Внизесть ли фанкция аналог sleep для своего потока ? Найти похожие ветки
← →
ali_tash (2005-02-08 21:52) [0]как я понял Sleep(1000) запрещает выполнятся главному потоку приложения на 1000 мс
а как можно запретить своему созданному потоку не работать какой нибудь интервал времени
Suspend замораживает поток но потом его надо Resumiть.
можно конечно использовать таймер , но как то не красиво
← →
Cobalt © (2005-02-08 23:42) [1]Есть такой замечтаельный файл - называется
C:\Program Files\Common Files\Borland Shared\MSHelp\WIN32.HLP
Поставляется вместе с Дельфи (как можно заметить из адреса, где он хранится).
Вот там и описано чётко и неоднозначно - что делает функция Sleep.
Очень рекомендую.
← →
Eraser © (2005-02-09 00:12) [2]ali_tash
Cobalt вещь говорит. F1 жми.
← →
Fay © (2005-02-09 05:03) [3]The Sleep function suspends the execution of the current thread for at least the specified interval.
← →
sniknik © (2005-02-09 08:38) [4]> как я понял Sleep(1000) запрещает выполнятся главному потоку приложения на 1000 мс
на больше. даже Sleep(0) может перекрыть интервал в 1000 мс. т.к. она не только "запрещает" но и отдает ресурсы другим потокам, а когда те вернут неопределено. (винда не реалтайм система)
← →
Игорь Шевченко © (2005-02-09 11:19) [5]
> даже Sleep(0) может перекрыть интервал в 1000 мс
Точно ?
← →
Владислав © (2005-02-09 11:39) [6]> Игорь Шевченко © (09.02.05 11:19) [5]
А разве нет?
Теоретический пример. Sleep в контексте потока, имеющего какой-то приоритет. За 1000 стартует поток, имеющий более высокий приоритет, который будет непрерывно работать в течении 10 секунд. Какой шанс у первого потока продолжить исполение через, хотя бы, 5 секунд после вызова Sleep?
← →
Игорь Шевченко © (2005-02-09 12:51) [7]Владислав © (09.02.05 11:39) [6]
> Какой шанс у первого потока продолжить исполение через,
> хотя бы, 5 секунд после вызова Sleep?
30%
← →
kaZaNoVa © (2005-02-09 15:05) [8]сделал тестовую программу .. у меня в таком виде показывает в среднем 25
program Project1;
uses
Windows,SysUtils;
{$R *.res}
Var
run:boolean;
p,tk:int64;
id:cardinal;
Procedure ThreadProc;
Var num,i:cardinal;
Begin
//SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_IDLE);
while not run do sleep(1); //ожидаем команды на старт
num:=GetTickCount;
i:=0;
repeat
sleep(1);
inc(i);
Until ((GetTickCount-num)>1000);
MessageBox(0,Pchar(IntToStr(i))," ",0);
run:=false;
End;
begin
run:=false;
//SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
CreateThread(nil,0,@ThreadProc,nil,0,id);
run:=true;
tk:=0;
While tk<1000000000 do tk:=tk+1;
repeat
sleep(11);
Until not run;
end.
← →
kaZaNoVa © (2005-02-09 15:06) [9]а с приоритетами вообще ThreadProc управления не получает .. (
← →
Владислав © (2005-02-09 15:25) [10]> Игорь Шевченко © (09.02.05 12:51) [7]
Ну хотя бы поясните свое мнение. Хоть ссылкой на материалы.
← →
Marser © (2005-02-09 15:25) [11]
> kaZaNoVa © (09.02.05 15:06) [9]
> а с приоритетами вообще ThreadProc управления не получает
> .. (
Может, critical это перебор?
← →
Игорь Шевченко © (2005-02-09 15:29) [12]Владислав © (09.02.05 15:25) [10]
Соломон, Руссинович - Внутреннее устройство Windows 2000, глава 6, планирование потоков.
Таненбаум - Современные операционные системы, глава 2.
← →
Digitman © (2005-02-09 15:30) [13]какие там нафих приоритеты ?
imho, вопрос автора неверно истолкован в принципе.
ибо изложен был крайне криво.
imho, автор желает в ТЕКУЩЕМ треде вызвать Suspend, при сем "заснуть беспробудным сном" и "проснуться" через N времени с того "места", где он, текущий тред, "заснул" при предыдущем Suspend ..
дурь она и есть дурь.
никто не понуждает автора вызывать Suspend дабы "заснуть с желанием проснуться через N времени" ... достаточно организовать никем (в рамках системы в целом) заведомо не "трогаемый" объект синхронизации (например, event) и вызвать вместо дурного sleep() ф-цию WaitForSingleObject(event_объект, время_ожидания_срабатывания_этого_объекта)
← →
Владислав © (2005-02-09 16:17) [14]> Игорь Шевченко © (09.02.05 15:29) [12]
К сожалению, книг этих у меня нет. Надо с этим как-то бороться :о)
Я, вообще-то, ориентировался на материалы, изложенные в книге Рихтера.
В общем, заинтриговали :)
← →
ali_tash (2005-02-09 19:32) [15]Digitman
можеш привести пример ?
← →
Fay © (2005-02-09 20:30) [16]2 Digitman © (09.02.05 15:30) [13]
Вас не затруднит пояснить, чем (в данном случае) "дурной" sleep хуже WaitForSingleObject?
← →
ali_tash (2005-02-09 21:39) [17]если я создам в своей программе поток с такими методами
procedure TMyThread1.DoWork;
begin
// например сюда Sleep(1000);
if Assigned(GOnTimer) then GOnTimer(Self);
end;
procedure TMyThread1.Execute;
begin
inherited;
while not Terminated do
Synchronize(DoWork);
end;
то когда будет срабатывать процедура sleep будет останавливаться выполнение самой программы ,а мне надо чтоб останавливался только мой поток.
а насчёт WaitForSingleObject это же процедура для паузы
программы которая запустила внешнюю программу до завершения внешней.
если я ошибаюсь то напишите пример как использовать WaitForSingleObject в моём случае.
← →
Alexander Panov © (2005-02-09 23:02) [18]ali_tash (09.02.05 21:39) [17]
Твоя ошибка в коде Synchronize(DoWork);
Разберись, как работает Synchronize.
← →
Alexander Panov © (2005-02-09 23:04) [19]ali_tash (09.02.05 21:39) [17]
Synchronize используется для выполнения кода в основном потоке, что ты успешно и делаешь непрерывно.
Пример можешь посмотреть вот здесь:
http://delphimaster.net/view/4-1107978628/
В примере не используется Synchronize, но, думаю, что дальше сам разберешься.
← →
Digitman © (2005-02-10 08:23) [20]
> ali_tash (09.02.05 19:32) [15]
> можеш привести пример ?
hEvent := CreateEvent(nil, false, false, nil);
try
case MsgWaitForMultipleObjects(1, hEvent, False, 1000, QS_ALLINPUT) of
WAIT_OBJECT_0: ..//просигналил ивент, пора просыпаться и работать дальше
WAIT_OBJECT_0 + 1:..//поступило сообщение, пора просыпаться и обработать его
WAIT_TIMEOUT: //спали секунду, за эту секунду ничего не произошло, пора просыпаться и работать дальше
finally
CloseHandle(hEvent);
end;
← →
Digitman © (2005-02-10 08:24) [21]"просыпаться" - это я лихо задвинул)
"проснуться" конечно же !
← →
ali_tash (2005-02-10 17:43) [22]спасибо
← →
Marser © (2005-02-10 18:06) [23]
> Digitman © (09.02.05 15:30) [13]
А что? Интересный вариант...
← →
sniknik © (2005-02-11 17:11) [24]Игорь Шевченко © (09.02.05 11:19) [5]
>> даже Sleep(0) может перекрыть интервал в 1000 мс
> Точно ?
а чего не точно, конечно точно, вариант есть может и на больше задержатся чем на секунду.
ну к примеру куча равноправных потоков (приоритет только запутывает, тем более система все равно повысит приоритет у давно ожидаюшего потока. т.что это только немного добавит времени к ожиданию (примем эту поправку коэффицентом ;о)))
ну вот, куча равноправных, у всех режим ожидания стоит sleep(0), можно прикинуть ожидаемое время будет приблизительно одинаковым. (никто ничего не делает, только система занята распределяет время "работы")
а теперь другая ситуация (кстати реальная, код такой видел) вся куча использует для задержки цикл
for i:= Low(Int64) to High(Int64) do ; (и так несколько раз на нужное количество мс)
и только один "добрый" сделал sleep(0)...
???
я лично затрудняюсь сказать на сколько времени будет в этом случае задержка у sleep-а. то что он получит управление, и даже до того как остальные закончат без вопросов, система постарается а вот время на которое прервется?
(естественно ситуация утрирована, просто показать максимальную загрузку)
← →
Игорь Шевченко © (2005-02-11 17:55) [25]sniknik © (11.02.05 17:11) [24]
> приоритет только запутывает, тем более система все равно
> повысит приоритет у давно ожидаюшего потока. т.что это только
> немного добавит времени к ожиданию
Это каким образом повышение приоритета добавляет время ожидания ?
> вся куча использует для задержки цикл
> for i:= Low(Int64) to High(Int64) do ; (и так несколько
> раз на нужное количество мс)
А какая разница, через квант все равно поток прервется и будет диспетчеризация.
> вариант есть может и на больше задержатся чем на секунду
Из серии: в военное время синус до 5 доходит ?
Ты бы лучше выложил код, который показывает, что поток, обратившийся к sleep(0) ждет больше секунды.
← →
Leonid Troyanovsky © (2005-02-12 00:58) [26]
> Игорь Шевченко © (11.02.05 17:55) [25]
> Ты бы лучше выложил код, который показывает, что поток,
> обратившийся к sleep(0) ждет больше секунды.
На двухпроцессорном w2k3 в Button2Click ждет и более 1 сек
(можно подобрать maxi)
type
TWorkThread = class(TThread)
procedure Execute; override;
end;
const
maxi = 100000000;
procedure TWorkThread.Execute;
var
i: Longint;
begin
Priority := tpHighest;
ReturnValue := 0;
for i := 0 to maxi do
if Terminated then
Break
else
ReturnValue := (ReturnValue + 1) mod maxi;
end;
var
t1, t2: TWorkThread;
procedure TForm1.Button1Click(Sender: TObject);
begin
t1 := TWorkThread.Create(False);
t2 := TWorkThread.Create(False);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
t : Longint;
begin
t := GetTickCount;
SetThreadPriority(GetCurrentThreadId, THREAD_PRIORITY_LOWEST);
Sleep(0);
SetThreadPriority(GetCurrentThreadId, THREAD_PRIORITY_NORMAL);
Caption := IntToStr(GetTickCount-t);
t1.Free;
t2.Free;
end;
Происходящее не очень удивительно, бо описано у Соломона-
Русиновича и, вроде, даже у Рихтера. Но, читать лениво,
а вспомнить могу лишь то, что давно не работавшим потокам
хоть и повышают приоритет, но не намного (на 2, кажись).
--
Regards, LVT.
← →
sniknik © (2005-02-12 02:51) [27]> Это каким образом повышение приоритета добавляет время ожидания ?
имелось ввиду при сравнении потоков с разными приоритетами, низкий будет ждать дольше (сказано чтобы исключить их из рассматривания, т.к. они все усложняют, а зачем это?), с высоким получает в первую очередь с низким "через раз", правильно? а вот если идут сплош задания с высокими приоритетами то низкому система временно повышает его, чтобы он совсем не у дел не оставался.
чтото типа этого, не специалист в этом, т.что точную картину "нарисовать" не могу (вернее могу но неохота углублятся в разбор ненужной области), но смысл верен.
> Из серии: в военное время синус до 5 доходит ?
> Ты бы лучше выложил код, который показывает, что поток, обратившийся к sleep(0) ждет больше секунды.
ну да, а косинус 18ти.
без проблем, простой перенос в код теоретической ситуации из -> sniknik © (11.02.05 17:11) [24]
unit ThreadUnit;
interface
uses
Classes, Windows, SysUtils, StdCtrls;
type
TFoolThread = class(TThread)
private
fFool, fShow: boolean;
fLabel: TLabel;
MaxWait: integer;
protected
procedure UpdateLabel;
procedure Execute; override;
public
constructor Create(nLabel: TLabel; nFool, nShow: boolean);
end;
implementation
constructor TFoolThread.Create(nLabel: TLabel; nFool, nShow: boolean);
begin
fFool:= nFool;
fShow:= nShow;
fLabel:= nLabel;
FreeOnTerminate:= true;
inherited Create(False);
end;
procedure TFoolThread.UpdateLabel;
begin
fLabel.Caption:= IntToStr(MaxWait);
end;
procedure TFoolThread.Execute;
var
i, CycleCount: integer;
StartMs, CountMs: integer;
begin
MaxWait:= 0;
CycleCount:= 100;
while (not Terminated) and (CycleCount > 0) do begin
if fFool then begin
for i:= Low(Integer) to High(Integer) do ;
end else begin
StartMs:= GetTickCount();
sleep(0);
CountMs:= GetTickCount() - StartMs;
if CountMs > MaxWait then MaxWait:= CountMs;
end;
Dec(CycleCount);
end;
if fShow then Synchronize(UpdateLabel);
end;
end.
и вызовы
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
for i:= 1 to 128 do
TFoolThread.Create(Label1, false, false);
TFoolThread.Create(Label1, false, true);
end;
procedure TForm1.Button2Click(Sender: TObject);
var i: integer;
begin
for i:= 1 to 128 do
TFoolThread.Create(Label1, true, false);
TFoolThread.Create(Label1, false, true);
end;
первая кнопка у меня выдала 80 мс, вторая (кстати предупреждаю очень длительная "операция", с практически полным повисанием системы надолго, даже после получения результата) 24656 мс (что согласитесь гораздо больше секунды)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.063 c