在匿名线程的上下文中访问局部变量是否安全?

杰森

在以下情况下,由匿名线程读取的DoSomething中的AValue值是否保证是“可读的”?即,我期望的价值?对我来说,我不认为DoSomething在线程实际执行之前就超出范围(即返回)(可以通过意识到x:= 2总是在线程开始之前执行来轻松看出-尽管我猜是与线程有关的)所有投注均关闭,并且我的线程可能在DoSomething返回之前执行)。

我只问是因为我在测试中从未遇到过AValue不等于1(也就是传入的值)的情况,所以我想知道是否对过程和/或线程保留了一些隐式引用(同样不太可能CreateAnonymousMethod只是创建一个TThread后代的实例(TAnonymousThread),并调用我的匿名“ execute”方法)。我猜是一样的,因为在这种有限的情况下,没有任何东西会覆盖存储AValue的内存位置。

procedure TForm2.Button1Click(Sender: TObject);
var
  x: Integer;
begin
  x := 1;
  DoSomething(x);
  x := 2;// this line is only here for the purposes of placing a break point
end;

procedure TForm2.DoSomething(AValue: Integer);
begin

  TThread.CreateAnonymousThread(
    procedure
    var
      y: Integer;
    begin
      y := AValue;

      if y = 1 then
        MessageBox(0, 'Same', 'Value', MB_ICONINFORMATION or MB_OK)
      else
        MessageBox(0, 'Different', 'Value', MB_ICONINFORMATION or MB_OK)
    end).Start;
end;

编辑只是为了验证,我想知道在匿名线程的上下文中捕获局部变量是否安全。

鲁道德

您正在按值传递x。这意味着x的值在您调用时被复制DoSomething()

因此,无论何时执行匿名线程,它都不会引用x。线程使用了一个捕获的变量,该变量用的原始值初始化x

换句话说,匿名线程无法查看您是否稍后在ButtonClick1事件中更改了x


注意,如果AValueDoSomething()构造匿名线程之后更改local in ,这将影响线程的结果。

procedure TForm2.DoSomething(AValue: Integer);
begin

  TThread.CreateAnonymousThread(
    procedure
    var
      y: Integer;
    begin
      y := AValue;

      if y = 1 then
        MessageBox(0, 'Same', 'Value', MB_ICONINFORMATION or MB_OK)
      else
        MessageBox(0, 'Different', 'Value', MB_ICONINFORMATION or MB_OK)
    end).Start;
  AValue := 3;  // <-- This value will likely be seen by the anonymous thread.
end;

如果要避免这种情况,可以捕获如下AValue值:

procedure TForm4.DoSomething(AValue: Integer);
   function CaptureValue( y: Integer) : TProc;
   begin
     Result :=
      procedure
      begin
       if y = 1 then
         MessageBox(0, 'Same', 'Value', MB_ICONINFORMATION or MB_OK)
       else
         MessageBox(0, 'Different', 'Value', MB_ICONINFORMATION or MB_OK)
     end;
   end;
var
  p : TProc;
begin
  p := CaptureValue(AValue);
  TThread.CreateAnonymousThread( p)
  .Start;
  AValue := 3; // <-- The anonymous method is unaffected by this change !
end;

文档解释说,外部局部变量AValue是通过匿名方法的引用来捕获的:

如果匿名方法在其主体中引用外部局部变量,则该变量将被“捕获”。捕获意味着延长变量的生存期,以使它的生存时间与匿名方法的值一样长,而不是死于其声明例程。请注意,变量捕获捕获变量,而不是值。如果通过构造匿名方法捕获变量后其值发生变化,则匿名方法捕获的变量值也将发生变化,因为它们是具有相同存储的相同变量。捕获的变量存储在堆中,而不是堆栈中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Java

防止在多线程上下文中使用非线程安全方法

来自分类Java

匿名类访问局部变量

来自分类Dev

静态局部变量的线程安全增量

来自分类Dev

为什么在多线程上下文中等待while循环条件是安全的?

来自分类Dev

线程安全局部变量

来自分类Dev

将上下文注入这样的eventlet线程是否安全?

来自分类Dev

在无效上下文中无用的匿名哈希({})

来自分类Dev

Kotlin局部变量线程安全

来自分类Dev

编译器错误说我没有分配局部变量,而在当前上下文中名称不存在?

来自分类Dev

Sfinae上下文中的模板变量

来自分类Dev

在调用上下文中访问局部变量

来自分类Dev

Javascript在Node.js上下文中访问ejs变量

来自分类Dev

局部变量是线程安全的吗?

来自分类Dev

发生名称冲突时,是否可以访问全局上下文中定义的变量?

来自分类Dev

更改JavaScript中的函数上下文(用于访问局部变量)

来自分类Dev

我如何将当前上下文保存到Javasccript中的局部变量

来自分类Dev

在此特定上下文中,从基层到派生的static_cast是否被视为“安全”?

来自分类Dev

线程上下文中的模板方法

来自分类Dev

在上下文中评估变量

来自分类Dev

在Vala中的foreach上下文中访问静态类变量

来自分类Dev

赋值之前引用的局部变量“上下文”

来自分类Dev

在多线程上下文中在映射中安全使用引用

来自分类Dev

Java局部变量线程安全

来自分类Dev

Django上下文:分配前引用的局部变量

来自分类Dev

函数上下文改变无法识别局部变量

来自分类Dev

Django 表单错误:赋值前引用了局部变量“上下文”

来自分类Dev

如何以线程安全的方式取消在 Solace 上下文中注册的计时器?

来自分类Dev

我可以在单线程上下文中安全地使用 Ordering::Relaxed 吗?

来自分类Dev

分配 Django 之前引用的 UnboundLocalError 局部变量“上下文”

Related 相关文章

  1. 1

    防止在多线程上下文中使用非线程安全方法

  2. 2

    匿名类访问局部变量

  3. 3

    静态局部变量的线程安全增量

  4. 4

    为什么在多线程上下文中等待while循环条件是安全的?

  5. 5

    线程安全局部变量

  6. 6

    将上下文注入这样的eventlet线程是否安全?

  7. 7

    在无效上下文中无用的匿名哈希({})

  8. 8

    Kotlin局部变量线程安全

  9. 9

    编译器错误说我没有分配局部变量,而在当前上下文中名称不存在?

  10. 10

    Sfinae上下文中的模板变量

  11. 11

    在调用上下文中访问局部变量

  12. 12

    Javascript在Node.js上下文中访问ejs变量

  13. 13

    局部变量是线程安全的吗?

  14. 14

    发生名称冲突时,是否可以访问全局上下文中定义的变量?

  15. 15

    更改JavaScript中的函数上下文(用于访问局部变量)

  16. 16

    我如何将当前上下文保存到Javasccript中的局部变量

  17. 17

    在此特定上下文中,从基层到派生的static_cast是否被视为“安全”?

  18. 18

    线程上下文中的模板方法

  19. 19

    在上下文中评估变量

  20. 20

    在Vala中的foreach上下文中访问静态类变量

  21. 21

    赋值之前引用的局部变量“上下文”

  22. 22

    在多线程上下文中在映射中安全使用引用

  23. 23

    Java局部变量线程安全

  24. 24

    Django上下文:分配前引用的局部变量

  25. 25

    函数上下文改变无法识别局部变量

  26. 26

    Django 表单错误:赋值前引用了局部变量“上下文”

  27. 27

    如何以线程安全的方式取消在 Solace 上下文中注册的计时器?

  28. 28

    我可以在单线程上下文中安全地使用 Ordering::Relaxed 吗?

  29. 29

    分配 Django 之前引用的 UnboundLocalError 局部变量“上下文”

热门标签

归档