更新值的多线程问题

本文关键字:问题 多线程 更新 | 更新日期: 2023-09-27 18:13:09

我很难理解为什么多线程在线程完成之前无法更新值。单独的线程有自己的引用或值的副本吗?


如果没有,根据我的理解,下面的代码应该在MyMethod被调用时正常工作,但通常在thread.IsAlive变为false之前,它不会在数组中创建一些MyType对象的实例:
class MyClass
{
    static MyType[] obj = new MyType[Environment.ProcessorCount - 1];
    void MyMethod()
    {
        Thread[] threads = new Thread[Environment.ProcessorCount - 1];
        for (int i = 0; i < Environment.ProcessorCount - 1; i++)
        {
            threads[i] = new Thread(() => FillObjects(i));
            threads[i].Priority = ThreadPriority.AboveNormal;
            threads[i].Start();
        }
        while (threads[i].Any(c => c.IsAlive))
        {
            Thread.Sleep(50);
        }
    }
    void FillObjects(int i)
    {
        obj[i] = new MyType();
        //perform actions with obj[i] to fill it with necessary values
    }
}

更新值的多线程问题

需要将循环变量的值赋给一个局部变量。否则,FillObjects(i)的第一次执行可能是在i递增之后执行的,因此FillObjects(0)从未被调用,因此obj[0]从未被分配。

void MyMethod()
{
    Thread[] threads = new Thread[Environment.ProcessorCount - 1];
    for (int i = 0; i < Environment.ProcessorCount - 1; i++)
    {
        int local = i;
        threads[i] = new Thread(() => FillObjects(local));
        threads[i].Priority = ThreadPriority.AboveNormal;
        threads[i].Start();
    }
    while (threads.Any(c => c.IsAlive))
    {
        Thread.Sleep(50);
    }
}

在多处理器机器上(必须有),由于缓存,在一个线程中写入内存位置的结果可能在另一个线程中不可见。使用Thread.VolatileReadThread.VolatileWrite read,以便"通过"缓存读写。

Cf。在c# 3.0中简单介绍线程这一章可以得到一个解释。(查找问题"Wait方法是否有可能写"False"?")。