TLa*_*ama 10 delphi multithreading
假设,我将有以下线程(请不要考虑在此示例的线程上下文执行方法中使用的内容,它仅用于解释):
type
TSampleThread = class(TThread)
private
FOnNotify: TNotifyEvent;
protected
procedure Execute; override;
public
property OnNotify: TNotifyEvent read FOnNotify write FOnNotify;
end;
implementation
procedure TSampleThread.Execute;
begin
while not Terminated do
begin
if Assigned(FOnNotify) then
FOnNotify(Self); // <- this method can be called anytime
end;
end;
Run Code Online (Sandbox Code Playgroud)
然后假设,我想OnNotify
在我需要的任何时候从主线程更改事件的方法.这个主线程实现事件处理程序方法作为ThreadNotify
方法:
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
FSampleThread: TSampleThread;
procedure ThreadNotify(Sender: TObject);
end;
implementation
procedure TForm1.ThreadNotify(Sender: TObject);
begin
// do something; unimportant for this example
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FSampleThread.OnNotify := nil; // <- can this be changed anytime ?
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FSampleThread.OnNotify := ThreadNotify; // <- can this be changed anytime ?
end;
Run Code Online (Sandbox Code Playgroud)
更改方法是否安全,可以随时从另一个线程的上下文中调用工作线程?做上面例子中显示的内容是否安全?
我不确定,如果那是绝对安全的,至少因为方法指针实际上是一对指针,我不知道我是否可以将它作为原子操作.
Cos*_*und 17
不,它不是线程安全的,因为该操作永远不会是"原子的".在TNotifyEvent
由两个指针,并在同一时间这些指针永远不会被分配给两个:一个将被分配,那么其他的将被分配.
为TNotifyEvent
赋值生成的32位汇编程序由两个不同的汇编程序指令组成,如下所示:
MOV [$00000000], Object
MOV [$00000004], MethodPointer
Run Code Online (Sandbox Code Playgroud)
如果它是一个单指针,那么你就有了一些选项,因为那个操作是原子的:你所拥有的选项取决于CPU的内存模型有多强:
Interlocked
方法.不幸的是,我不知道当前Intel CPU的内存模型有多强.有一些间接证据表明可能会发生一些重新排序,建议使用这些重新排序Interlocked
,但我还没有看到英特尔发表的明确声明中的一个或另一个.
证据:
归档时间: |
|
查看次数: |
847 次 |
最近记录: |