Ata*_*era 3 delphi multithreading tstringlist
没有任何形式的同步从TStringList读取数据是否可以?例如,与主线程同步.
示例代码
var MyStringList:TStringList; //declared globally
procedure TForm1.JvThread1Execute(Sender: TObject; Params: Pointer);
var x:integer;
begin
for x:=0 to MaxInt do MyStringList.Add(FloatToStr(Random));
end;
procedure TForm1.ButtonClick(Sender: TObject);
var x:integer;
SumOfRandomNumbers:double;
begin
for x:=0 to MyStringList.Count-1 do
SumOfRandomNumbers:=SumOfRandomNumbers+StrToFloat(MyStringList.Strings[x]);
end;
Run Code Online (Sandbox Code Playgroud)
或者我应该使用EnterCiticalSection保护对MyStringList的访问
var MyStringList:TStringList; //declared globally
procedure TForm1.JvThread1Execute(Sender: TObject; Params: Pointer);
var x:integer;
begin
for x:=0 to MaxInt do
begin
EnterCriticalSection(MySemaphore);
MyStringList.Add(FloatToStr(Random));
LeaveCriticalSection(MySemaphore);
end;
end;
procedure TForm1.ButtonClick(Sender: TObject);
var x:integer;
SumOfRandomNumbers:double;
begin
for x:=0 to MyStringList.Count-1 do
begin
EnterCriticalSection(MySemaphore);
SumOfRandomNumbers:=SumOfRandomNumbers+StrToFloat(MyStringList.Strings[x]);
LeaveCriticalSection(MySemaphore);
end;
end;
Run Code Online (Sandbox Code Playgroud)
Dis*_*ned 16
首先,no TStringList不是线程安全的.
其次,尝试制作它对于低级容器来说是一个糟糕的想法,在绝大多数情况下,不会在多个线程之间共享.
第三,你提出的使线程安全的天真代码是不够的.它远远没有使它真正的线程安全 - 这是尝试这样做的一般问题的一部分.
在你的问题的文本中,你问:
没有任何形式的同步从TStringList读取数据是否可以?
是的没关系.事实上,这是首选,因为它更有效.
但是,如果跨线程共享数据,则可能会遇到问题.这就是为什么你应该最小化跨线程共享的数据量(不仅仅是字符串列表).如果您确实需要共享数据,请以适当的控制方式进行.
您的代码不是线程安全的原因是它无法保护您的所有数据免受共享访问.这是多线程开发中常见的误解:" 我只需要使用锁来包装某些操作,一切都会好的. "
关键是,如果您的列表是共享的,您将:
虽然您提出的锁定策略可能适合您当前的要求,但它通常不是一般的线程安全的.
如果你想编写线程安全的代码,那么onus就是你:
我之前曾表示,您的锁定技术" 可能适合您当前的要求 ",因为我不相信您确实已经指出了您的实际要求.如果您有,那么您确实需要注意以下事项:
在您提供的代码中,使您的TStringList"线程安全" 绝对没有任何好处.您在循环中填充列表,并在第二个循环中读取值.你正在做绝对没有使用的数据并发.
你的代码最接近多线程的是:最好从主线程处理两个循环以避免阻塞UI.在这种情况下,后台线程应不共享其TStringList实例.并且可以简单地与主线程同步以报告结果(以及可能的进度更新).
通过不共享不需要共享的数据,您可以完全绕过对锁的需求.它们将是不必要的开销.你可以很高兴TStringList 没有内置的"线程安全"机制.
| 归档时间: |
|
| 查看次数: |
1816 次 |
| 最近记录: |