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

Вниз

есть ли фанкция аналог 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 вся ветка

Текущий архив: 2005.03.27;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.037 c
3-1109234184
Shuma
2005-02-24 11:36
2005.03.27
Нужен компонент наследник от TDataSet


3-1109582174
GebbelZ
2005-02-28 12:16
2005.03.27
доступность InterBase


1-1110477507
greysers
2005-03-10 20:58
2005.03.27
Как определить что OLE automation object закончил свою работу ?


6-1106643851
Redis
2005-01-25 12:04
2005.03.27
Удалённый доступ.


3-1109412494
Walker
2005-02-26 13:08
2005.03.27
Нужен компонент а-ля Access "поле со списком"