首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi -从第二个线程更新全局字符串

Delphi -从第二个线程更新全局字符串
EN

Stack Overflow用户
提问于 2011-10-16 00:42:21
回答 1查看 2.8K关注 0票数 9

我正在Delphi (XE)中试验多线程,在主VCL线程和第二个工作线程之间使用全局变量时遇到了一个问题。

我的项目涉及第二个工作线程,它扫描一些文件,并用当前文件名更新一个globalvar字符串。然后,通过主VCL线程上的计时器获取该globalvar,并更新状态栏。

但我注意到,它偶尔会出现“无效指针操作”或“内存不足”,或者工作线程停止响应(可能是死锁)。

因此,我创建了一个测试应用程序来识别并极大地增加出错的机会,这样我就可以看到发生了什么。

代码语言:javascript
复制
type
  TSyncThread = class(TThread)
  protected
    procedure Execute; override;
end;

var
  Form11: TForm11;
  ProgressString : String;
  ProgressCount : Int64;
  SyncThread : TSyncThread;
  CritSect : TRTLCriticalSection;

implementation

{$R *.dfm}

procedure TForm11.StartButtonClick(Sender: TObject);
begin
  Timer1.Enabled := true;
  SyncThread := TSyncThread.Create(True);
  SyncThread.Start;
end;

procedure TForm11.StopbuttonClick(Sender: TObject);
begin
  Timer1.Enabled := false;
  SyncThread.Terminate;
end;

procedure TForm11.Timer1Timer(Sender: TObject);
begin
  StatusBar1.Panels[0].Text := 'Count: ' + IntToStr(ProgressCount);
  StatusBar1.Panels[1].Text := ProgressString;
end;

procedure TSyncThread.Execute;
var
  i : Int64;
begin
  i := 0;
  while not Terminated do begin
    inc(i);
    EnterCriticalSection(CritSect);
    ProgressString := IntToStr(i);
    ProgressCount := i;
    LeaveCriticalSection(CritSect);
  end;
end;

initialization
  InitializeCriticalSection(CritSect);
finalization
  DeleteCriticalSection(CritSect);

我将计时器间隔设置为10ms,以便它读取大量数据,同时工作线程正在全力更新全局变量字符串。果不其然,这个应用程序在运行时几乎不会持续一秒,就会出现上述错误。

我的问题是,VCL定时器中全局变量的读取操作是否需要在临界区运行?-如果需要,为什么?根据我的理解,这只是一次读取,并且写入已经在临界区运行,我看不出它为什么会遇到问题。如果我把计时器中的读数也放入一个临界区--它是有效的,fine....but,我不高兴这样做,却不知道为什么!

我是多线程的新手,所以如果能帮助我解释为什么这个简单的例子会导致各种问题,以及是否有更好的方法从工作线程访问字符串,我将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-16 00:50:02

Delphi字符串是在堆上分配的,它不是某个地方的静态缓冲区。变量本身只是一个指针。当你的读线程访问一个字符串,同时这个字符串被另一个线程释放时,糟糕的事情就会发生。您正在访问已释放的内存,可能会再次分配给其他内存,等等。

即使这个字符串是一个静态缓冲区,更新操作也不是原子的,因此您可能正在使用一个正在更新的损坏的字符串(一半是新数据,另一半是旧数据)。

因此,您需要使用与写入操作相同的临界区来保护您的读取操作。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7779174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档