代码很简单,就那么几行。
主要就是想看,线程是否 Sleep 了我设置的秒数,例如我代码写 Sleep(10),我就想看看 它是否真的睡了 10ms 。
代码如下:
Form:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
MyThread;type
TForm1 = class(TForm)
Memo1: TMemo;
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
FMyThread:TMyThread;
procedure OnMY(var mesg:TMessage);message WM_MY;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.OnMY(var mesg:TMessage);//message WM_MY;
begin
Memo1.Lines.Add(inttostr(mesg.LParam));
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if FMyThread=nil then
FMyThread := TMyThread.Create(StrToInt(trim(Edit1.Text)) , self.Handle);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if FMyThread<>nil then
FreeAndNil(FMyThread);
end;end.
线程:
unit MyThread;interfaceuses
Classes, Messages, Windows;const
WM_MY = WM_USER + 100;type
TMyThread = class(TThread)
private
FInterval:integer;
FOwnerWND:THandle; FTick1:integer;
FTick2:integer;
protected
procedure Execute; override;
public
Constructor Create(const AInterval:integer;const AOwnerWND:THandle);
destructor Destroy;override;
end;implementation{ TMyThread }Constructor TMyThread.Create(const AInterval:integer;const AOwnerWND:THandle);
begin
inherited Create(true); FInterval:=AInterval;
FOwnerWND:=AOwnerWND; self.Resume;
end;destructor TMyThread.Destroy;//override;
begin
self.Terminate;
self.WaitFor;
inherited;
end;procedure TMyThread.Execute;
begin
while not self.Terminated do
begin
Sleep(FInterval);
FTick2:=GetTickCount;
PostMessage(FOwnerWND,WM_MY,0,FTick2-FTick1);
FTick1:=FTick2;
end;
end;end.
情况一:
机子里没开别的软件,我点击 Button1 ,一会后点击 Button2 ,结果如下图:看到基本 我设了 Sleep 5ms,但是 它睡了 15ms,我想应该是线程 时间片 的原因吧??-------(1)情况二:
我开了 PPStream 在看,然后运行 该程序,点击 Button1 一会后点击 Button2,结果如下图:这个我就有点想不通了,为什么是这样的结果??? ------ (2)请对上面两个问题(1)(2)进行解答,谢谢。PS:机子 P4 2.8 单核,XP pro sp2
主要就是想看,线程是否 Sleep 了我设置的秒数,例如我代码写 Sleep(10),我就想看看 它是否真的睡了 10ms 。
代码如下:
Form:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
MyThread;type
TForm1 = class(TForm)
Memo1: TMemo;
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
FMyThread:TMyThread;
procedure OnMY(var mesg:TMessage);message WM_MY;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.OnMY(var mesg:TMessage);//message WM_MY;
begin
Memo1.Lines.Add(inttostr(mesg.LParam));
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if FMyThread=nil then
FMyThread := TMyThread.Create(StrToInt(trim(Edit1.Text)) , self.Handle);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if FMyThread<>nil then
FreeAndNil(FMyThread);
end;end.
线程:
unit MyThread;interfaceuses
Classes, Messages, Windows;const
WM_MY = WM_USER + 100;type
TMyThread = class(TThread)
private
FInterval:integer;
FOwnerWND:THandle; FTick1:integer;
FTick2:integer;
protected
procedure Execute; override;
public
Constructor Create(const AInterval:integer;const AOwnerWND:THandle);
destructor Destroy;override;
end;implementation{ TMyThread }Constructor TMyThread.Create(const AInterval:integer;const AOwnerWND:THandle);
begin
inherited Create(true); FInterval:=AInterval;
FOwnerWND:=AOwnerWND; self.Resume;
end;destructor TMyThread.Destroy;//override;
begin
self.Terminate;
self.WaitFor;
inherited;
end;procedure TMyThread.Execute;
begin
while not self.Terminated do
begin
Sleep(FInterval);
FTick2:=GetTickCount;
PostMessage(FOwnerWND,WM_MY,0,FTick2-FTick1);
FTick1:=FTick2;
end;
end;end.
情况一:
机子里没开别的软件,我点击 Button1 ,一会后点击 Button2 ,结果如下图:看到基本 我设了 Sleep 5ms,但是 它睡了 15ms,我想应该是线程 时间片 的原因吧??-------(1)情况二:
我开了 PPStream 在看,然后运行 该程序,点击 Button1 一会后点击 Button2,结果如下图:这个我就有点想不通了,为什么是这样的结果??? ------ (2)请对上面两个问题(1)(2)进行解答,谢谢。PS:机子 P4 2.8 单核,XP pro sp2
用 GetThreadTimes吧
Sleep(X)的意思是使该线程放弃X毫秒的时间片的竞争!
当X毫秒过后,该线程醒来后,有了竞争时间片的权利,但这时很可能其它线程对CPU享有控制权。
所以需要排队!
procedure TMyThread.Execute;
begin
while not self.Terminated do
begin
Sleep(FInterval); // 这里放弃时间片
FTick2:=GetTickCount; //等到可以运行时,获得Tick数
PostMessage(FOwnerWND,WM_MY,0,FTick2-FTick1);
//FTick2-FTick1 ---> 应该是这一次的GetTickCount,与上一次GetTickCount的时间差
FTick1:=FTick2;
end;
end;
我是不明白:在开了PPStream后,为何 "FTick2-FTick1" 会有 "0" 出现???
asm
DB $0F, $31 //rdtsc
end;var
t1, t2: int64;
begin
t1 := GetCPUTimeCount;
sleep(1);
t2 := GetCPUTimeCount;
//t1, t2再除以你的CPU主频,相减可以得到精确的时间
end;
另外,windows7下GetLocalTime精度可以到1毫秒
但是,在开了 PPS 后却,得到了不正确的值 --> 睡了 小于 15ms现在问题就是:如何在 开PPS 的情况下,得到正确的值???
用了这个方式,代码改为:function GetCPUTimeCount: Int64;
asm
DB $0F, $31 //rdtsc
end;procedure TMyThread.Execute;
var timePoint1:TDatetime;
timePoint2:TDatetime;
passTime:Int64; i,j:integer;
Tick1:integer;
Tick2:integer; t1, t2: int64;
t:integer;
begin
while not self.Terminated do
begin
//{
t1 := GetCPUTimeCount;
sleep(FInterval);
t2 := GetCPUTimeCount;
//t1, t2再除以你的CPU主频,相减可以得到精确的时间
t:=(t2-t1) div 2800000;
PostMessage(FOwnerWND,WM_MY,0,t);
//}
end;
end;
机子空闲时,如下图:
开PPS后,如图:
Sleep(1) 和 Sleep(5) 得到的结果 都小于15ms,这个结果应该是不对的吧??
你的第一个例子,如果把sleep 5 改成 50,应该可以看到偏差,不会是0
不开PPS:开PPS:
timeBeginPeriod、timeEndPeriod、timeSetEvent、timeKillEvent这几个函数,貌似是用来做毫秒级定时器的。
如何用它们 来达到我的要求(看 线程到底 睡了多久)???
2》
3》
4》createthread(...) 假如这个线程要运行10秒
5》sleep(x)此时主线程sleep了,会对已在运行中thread有影响吗?