2008/10/20

Windows delay problem

Мэргэжил нэгт нөхөд минь ээ надад нэг асуудал тулгараад байна. Delphi дээр sleep(1) гэсэн sleep(10) гэсэн хоёр ямарч ялгаагүй хугацаа зарцуулаад байна. Дан ганц Delphi биш C# дээр бас энэ асуудал гарч байсан. Уул нь sleep(1) нь 1 миллисекунд, sleep(10) нь 10 миллисекунд хугацаа зарцуулмаар юм. Гэхдээ бас дандаа ийм бишээ. Хааяа зүгээр болчихдог. Энэ их сонирхолтой байгаамаа. Яг юунаас шалтгаалаад ийм гажиг үүсээд байгааг би сайн мэдэхгүй байна. Та нарт ийм асуудал тулгарч байсан уу?

Энийг зүгээр болгодог нэг тохиолдол олсон л доо. Өөрийн компьютер дээрээ Virtual Machine (VMWare) ажиллуулахаар зүгээр болчихдог юм байна лээ.

Энэ асуудлыг шийдэх арга байна уу? Туслаарай.

Delphi код


unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;

type

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMProgrsThread = class (TThread)
FX, FY, FDelay: integer;
procedure Execute; override;
constructor Create(AX, AY, ADelay: integer);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

constructor TMProgrsThread.Create;
begin
inherited Create(False);
FX:=300;
FY:=AY;
FDelay:=ADelay;
FreeOnTerminate:=True;
end;

procedure TMProgrsThread.Execute;
begin
while not Terminated do begin
if FX>0 then FX:=FX-1 else FX:=300;
Form1.Canvas.Lock;
Form1.Canvas.Rectangle(FX, FY, FX+50, FY+50);
form1.Canvas.Unlock;
Sleep(FDelay);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var t1, t2: TMProgrsThread;
begin
t1:=TMProgrsThread.Create(10, 30, 1);
t2:=TMProgrsThread.Create(10, 100, 10);
end;

end.


6 comments:

D.Enkhbat - Д.Энхбат said...

1, 10 хоёрын ялгаагаа яаж мэдэрч байна? C# дээр бол Thread.Sleep(1) гэж бичиж болно.

class Test
{
static TimeSpan waitTime = new TimeSpan(0, 0, 1);

public static void Main()
{
Thread newThread =
new Thread(new ThreadStart(Work));
newThread.Start();

if(newThread.Join(waitTime + waitTime))
{
Console.WriteLine("New thread terminated.");
}
else
{
Console.WriteLine("Join timed out.");
}
}

static void Work()
{
Thread.Sleep(waitTime);
}
}

Мөнх-Эрдэнэ said...

Энд хийж байгаа үйлдэлийг нь харахад ойлгомжтой биш байна гэж үү? 2 thread хоёулаа нэг нэг ширхэг дөрвөлжинг хөдөлгөнө. Харин хөдөлгөх хурд нь 1:10 байх ёстой байтал 10:10 буюу ижилхэн болчихоод байна л даа. Энэ асуудал програмчлалын хэлнийх биш windows-ийн асуудал юм шиг санагдаад байна

Anonymous said...

Naadah chini boldoggui yumaa yamar ch heldeer ijilhen

D.Enkhbat - Д.Энхбат said...

Үйлдлийг нь бол хараад ойлгож байна. Харин 1, 10-ийн миллисекундын зөрүүг яаж мэдрээд байнаа гэдэг л ... хэхэ.

Мөнх-Эрдэнэ said...

Sleep(FDelay); гээд байгаа биздээ. Thread create хийхдээ FDelay:=ADelay гээд өгчихсөн байгаа.

D.Enkhbat - Д.Энхбат said...

Аан за. Энэ тохиолдолд зөрөө гарч байгаа эсэхийг нь ганц өгөгдөл дээр биш. Нэлээн хэдэн өгөгдөл шалгавал зөв ажиллаж байгаа эсэх нь мэдэгдэх юм бишүү? Жишээлбэл:
Функц 1.
Sleep(1);Sleep(1);Sleep(1);Sleep(1);Sleep(1);
Функц 2.
Sleep(10);Sleep(10);Sleep(10);Sleep(10);Sleep(10);
Энэ хоёрын зөрүү чинь 50 - 5 = 45 гарах ёстой. Ингэх тусам зөв гарах магадлал нь ихэсдэг. Өөрөөр хэлбэл, Тухайн үйлдлийг гүйцэтгэх хугацаа ороод бараг ялгаагүй мэт харагдаад байгаа байх.