使用定时器和其它线程之间临界区的多线程同步的Delphi(Multi-threading Delph

2019-08-05 19:29发布

它是同步的问题。 我做了一个简化我的问题,所以我有一个VCL定时器和线程数。 该线程试图写的东西在两个位图,以及定时器试图将位图绘制成图像(TImage中)。 这里是我的代码修改更容易理解(本贴的代码是非常模糊)。

//------------------------------------------------------------------------------
Procedure TMyForm.Add(iX,iY,iNr:integer);
begin
   EnterCriticalSection(csCriticalSection);
   bmRed.Canvas.Lock;
   bmBlue.Canvas.Lock;

   //.... drawing etc...
   bmRed.Canvas.TextOut(iX,iY,IntToStr(iNr));
   bmBlue.Canvas.TextOut(iX,iY,IntToSTr(iNr));

   bmRed.Canvas.Unlock;
   bmBlue.Canvas.Unlock;

   LeaveCriticalSection(csCriticalSection);
end;
//------------------------------------------------------------------------------
procedure TMyForm.tmTimer(...);
begin
   EnterCriticalSection(csCriticalSection);

   bmRed.Canvas.Lock;
   bmBlue.Canvas.Lock;

   //Drawing on bmRed and bmBlue
   imBlue.Canvas.Draw(bmBlue);
   imRed.Canvas.Draw(bmBlue);

   bmRed.Canvas.Unlock;
   bmBlue.Canvas.Unlock;

   LeaveCriticalSection(csCriticalSection);
end;
//------------------------------------------------------------------------------
Procedure TMyThread.Execute();
begin
   Randomize;
   while not terminated do
   begin
      MyFormInstance.Add(Random(100),Random(100),Random(100));

      Sleep(20);
   end;
end;

initialization
   InitializeCriticalSection(csCriticalSection);
finalization
   DeleteCriticalSection(csCriticalSection);

通常情况下,线程临界区或几秒钟后,定时器进入将不再吸引我什么时候给我的错误。

Answer 1:

尝试添加异常处理代码,并且不锁定在同一时间两个位图:

var
  csCriticalSection: TRTLCriticalSection;

procedure TMyForm.Add(iX,iY,iNr:integer);
begin
  EnterCriticalSection(csCriticalSection);
  try
    bmRed.Canvas.Lock;
    try
      bmRed.Canvas.TextOut(iX,iY,IntToStr(iNr));
    finally
      bmRed.Canvas.Unlock;
    end;

    bmBlue.Canvas.Lock;
    try
      bmBlue.Canvas.TextOut(iX,iY,IntToSTr(iNr));
    finally
      bmBlue.Canvas.Unlock;
    end;
  finally
     LeaveCriticalSection(csCriticalSection);
  end;
end;

procedure TMyForm.tmTimer(Sender: TObject);
begin
  EnterCriticalSection(csCriticalSection);
  try
    bmRed.Canvas.Lock;
    try
      imRed.Canvas.Draw(bmBlue);
    finally
      bmRed.Canvas.Unlock;
    end;

    bmBlue.Canvas.Lock;
    try
      imBlue.Canvas.Draw(bmBlue);
    finally
      bmBlue.Canvas.Unlock;
    end;
  finally
    LeaveCriticalSection(csCriticalSection);
  end;
end;

procedure TMyThread.Execute;
begin
  Randomize;
  while not Terminated do
  begin
    MyFormInstance.Add(Random(100),Random(100),Random(100));
    Sleep(20);
  end;
end;

initialization
  InitializeCriticalSection(csCriticalSection);
finalization
  DeleteCriticalSection(csCriticalSection);

如果仍然会崩溃/示数,那么你必须在你的代码还没有表现出不同的错误。 特别是考虑到,你不应该得到一个错误进入/离开一个关键部分,除非临界区本身损坏。



文章来源: Multi-threading Delphi synchronization using Critical Sections between a Timer and other threads