Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.03 c
1-1110971671
aleshap
2005-03-16 14:14
2005.03.27
Event OnEnter


9-1104846353
Trof
2005-01-04 16:45
2005.03.27
glscene


3-1109593023
mrAld
2005-02-28 15:17
2005.03.27
ADONET и ADO


3-1109714894
Arazel
2005-03-02 01:08
2005.03.27
А как сравнить месяц и год в DataField с помощью SQL ?


1-1110529268
Гость
2005-03-11 11:21
2005.03.27
Кнопка close (x) в верхнем левом (правом) углу





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