Joh*_*ica 10 delphi string parameters const
这段代码
procedure MyThreadTestA(const AStr: string);
Run Code Online (Sandbox Code Playgroud)
比快
procedure MyThreadTestB(AStr: string);
Run Code Online (Sandbox Code Playgroud)
在做同样的工作时,都会传递一个指针.
但是,版本B'正确'更新了引用计数,AStr并在我更改它时进行复制.
版本A只传递一个指针,只有编译器阻止我改变AStr.
如果我在汇编程序中使用脏技巧或以其他方式规避编译器保护,则版本A不安全,这是众所周知的但是......
通过AStr引用传递作为const参数线程安全吗?
如果AStr某个其他线程中的引用计数变为零并且字符串被销毁会发生什么?
Bar*_*lly 16
不,这样的技巧不是线程安全的.Const防止add-ref,因此另一个线程的更改将以不可预测的方式影响该值.示例程序,尝试修改const以下定义P:
{$apptype console}
uses SysUtils, Classes, SyncObjs;
type
TObj = class
public
S: string;
end;
TWorker = class(TThread)
public
procedure Execute; override;
end;
var
lock: TCriticalSection;
obj: TObj;
procedure P(const x: string);
// procedure P(x: string);
begin
Writeln('P(1): x = ', x);
Writeln('Releasing obj');
lock.Release;
Sleep(10); // give worker a chance to run
Writeln('P(2): x = ', x);
end;
procedure TWorker.Execute;
begin
// wait until TMonitor is freed up
Writeln('Worker started...');
lock.Acquire;
Writeln('worker fiddling with obj.S');
obj.S := 'bar';
TMonitor.Exit(obj);
end;
procedure Go;
begin
lock := TCriticalSection.Create;
obj := TObj.Create;
obj.S := 'foo';
UniqueString(obj.S);
lock.Acquire;
TWorker.Create(False);
Sleep(10); // give worker a chance to run and block
P(obj.S);
end;
begin
Go;
end.
Run Code Online (Sandbox Code Playgroud)
但它不仅限于线程; 修改基础变量位置具有类似的效果:
{$apptype console}
uses SysUtils, Classes, SyncObjs;
type
TObj = class
public
S: string;
end;
var
obj: TObj;
procedure P(const x: string);
begin
Writeln('P(1): x = ', x);
obj.S := 'bar';
Writeln('P(2): x = ', x);
end;
procedure Go;
begin
obj := TObj.Create;
obj.S := 'foo';
UniqueString(obj.S);
P(obj.S);
end;
begin
Go;
end.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1465 次 |
| 最近记录: |