【问题标题】:C# Multithreading Pass by value or reference?C#多线程按值或引用传递?
【发布时间】:2013-07-20 09:37:12
【问题描述】:

我在网上看到一段代码,指出调用这样的线程会导致不确定的输出“0223557799”或类似的东西。(你明白了)

for (int i = 0; i < 10; i++)
   new Thread (() => Console.Write (i)).Start();

这是给出的原因:

“问题在于 i 变量在循环的整个生命周期中都指向同一个内存位置。因此,每个线程都会调用 Console.Write 变量,其值可能会在运行时发生变化!”

但是,按照惯例,当参数按值传递时 - 每个新的 Thread 调用都应该发送 i 其增量顺序对吗?只有当值通过引用传递时,上述原因才成立。那么,在 C# 多线程中,值是通过引用传递的吗?

我是C#的新手,如果这个问题很幼稚,请理解。

【问题讨论】:

  • int temp = i;将它放在循环中并传递温度,slaks 是对的。

标签: c# multithreading variables memory-management pass-by-reference


【解决方案1】:

你的程序等价于下面的程序:

class Locals
{
    public int i;
    public void M() { Console.Write(this.i);
}

...
Locals locals = new Locals();
for (locals.i = 0; locals.i < 10; locals.i++)
  new Thread (locals.M).Start();

现在你清楚为什么你会得到你所做的结果吗?按值传递的不是i;而是locals通过引用 传递给每个线程。每个线程共享locals.i,因此可以看到locals.i当前值,而不是创建线程时i 的值。

【讨论】:

    【解决方案2】:

    这里有不止一个问题。它肯定是从 for() 循环变量捕获问题开始的,在 blog post 中进行了描述。这往往会产生“10”作为输出,但不能保证会发生这种情况,因为线程可能会在循环仍在迭代时执行。

    但该程序也存在核心线程问题,无法保证线程会按预期顺序调用 Console.Write()。这只是可能,但一个线程可能会领先于另一个线程并获得保护控制台的锁。称为“threading race”的问题。

    【讨论】:

    • C# 5 中的更改仅适用于 foreach 循环,不适用于 for 循环。
    猜你喜欢
    • 2012-01-16
    • 2012-10-14
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    相关资源
    最近更新 更多