代码之家  ›  专栏  ›  技术社区  ›  miguel

线程本地存储和本地方法变量

  •  2
  • miguel  · 技术社区  · 16 年前

    在c#中,每个线程都有自己的堆栈空间。

    如果是这样,为什么下面的代码不是线程安全的(据称,本规范 是 这篇文章的线程安全: Locking in C#

    class Foo 
    { 
        private int count = 0; 
        public void TrySomething()     
        { 
            count++; 
        } 
    } 
    

    因为count是一个int(堆栈变量),所以这个值肯定会被隔离到一个单独的线程,在它自己的堆栈上,因此线程安全吗?

    我可能在这里遗漏了一些东西,但是如果不是线程的基于堆栈的变量,我不明白线程本地存储中到底有什么?

    另外,本地声明的变量呢:

    class Foo 
    { 
        public void TrySomething(object myObj)     
        { 
           var localVariable = new object();
           localVariable = myObj;
        } 
    } 
    

    3 回复  |  直到 9 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    Count是类的成员变量 Foo 福 是一种引用类型,它存储在堆而不是堆栈上。

    如果只创建了1 福 对象并允许两个单独的线程调用 TrySomething() sample code )

    结构和类之间的区别不在于它们是存储在堆还是堆栈上。这是一个常见的误解。将类看作指向堆上存储的指针。把结构看作是本地存储的直接值。在一个非常简单的层次上,这确实意味着结构通常存储在堆栈上,但这并不是如本例所示的所有情况下都是这样。

        2
  •  2
  •   Darin Dimitrov    16 年前

    Foo count 变量将相同:

    var foo = new Foo();
    new Thread(foo.TrySomething).Start();
    new Thread(foo.TrySomething).Start();
    

    TrySomething方法将在两个不同的线程上同时执行 变量,所以每次访问 计数

    public void TrySomething()     
    { 
        Interlocked.Increment(ref count);
    } 
    
        3
  •  2
  •   John Källén    16 年前

    但是数一数 不是吗 堆栈变量;它是一个类的成员变量。如果传递对的实例的引用 Foo

    而不是特定的班级。把它看作全局变量(或类的静态成员变量),不同的是它们的作用域仅在单个线程中可见;其他线程甚至看不见。它们不存储在线程的堆栈中,而是存储在线程专用的特殊区域中。

    不过,仍有麻烦的余地。如果存储对 福