【问题标题】:C# Multithreading synchronizationC# 多线程同步
【发布时间】:2011-04-04 19:20:57
【问题描述】:

我正在做一个需要多线程同步的程序。这是我的方法:

    private void RunSimulation()
    {
        int sideSize = (int)Math.Ceiling((double)_simulationField.GetLength(0) / (double)MAX_SECTOR_SIZE);
        int threadsCount = sideSize * sideSize;
        sync = new bool[threadsCount + 1];
        for (int i = 0; i < sync.Length; i++)
        {
            sync[i] = false;
        }
            for (int sector = 0; sector <= threadsCount; sector++)
            {
                Thread sectorThread = new Thread(DoSector);
                sectorThread.IsBackground = true;
                sectorThread.Start(sector);
            }
    }

还有:

    private void DoSector(object obj)
    {
        int sector = (int)obj;
        Library.Pair sectorPosition = GetSectorPosition(sector);
        while (true)
        {

            for (int i = sectorPosition.X; i < sectorPosition.X + MAX_SECTOR_SIZE && i < _simulationField.GetLength(0); i++)
            {
                for (int j = sectorPosition.Y; j < sectorPosition.Y + MAX_SECTOR_SIZE && j < _simulationField.GetLength(1); j++)
                {
                    if (_simulationField[i, j] != null)
                    {
                        MoveCreature(_simulationField[i, j], i, j);
                    }
                }
            }
            sync[sector] = true;
            while (sync.Contains(false) && sector != sync.Length)
            {
                Thread.Sleep(10);
            }
            if (sector == sync.Length)
            {
                for (int i = 0; i < sync.Length; i++)
                {
                    sync[i] = true;
                }
            }
            Thread.Sleep(500);
        }
    }

所以你可以看到我正在使用一个数组进行同步。但我在徘徊是这样做的好方法吗?这里的 sync.Contains 操作复杂度为 O(n),并且处于循环中...有没有更好的同步方法?

【问题讨论】:

    标签: c# multithreading synchronization


    【解决方案1】:

    我想你想在这里使用Barrier。它是一个允许线程分阶段执行的同步对象。所有线程必须在一个阶段完成它们的计算,然后才能执行下一个阶段。这正是您所需要的。

    【讨论】:

      【解决方案2】:

      使用数组进行同步不是线程安全的,而是单独使用“sync.Contains(false)”。

      如果两个线程同时运行 sync.Contains(false) 并且都返回 false 怎么办?

      另外,我看到您的 ThreadCount 是 sideSize 的平方。创建大量线程是非常低效的。您拥有的线程越多,您拥有的上下文切换就越多。上下文切换大约需要 8000 个时钟周期。此外,创建一个线程需要大约 100,000 个时钟周期,并且每个线程必须有自己的堆栈,默认情况下约为 4MB。

      您想要的是与内核一样多的线程以及从队列中拉出并处理其工作的每个线程。

      您可能最好使用线程池,但我也看到您的线程在一段时间内(真),这意味着它们永远不会结束。线程池不适用于长时间运行的线程。

      总的来说,我认为您的设计需要一些工作。既然你似乎在学习,我会推荐一种允许使用线程池的设计,而不是 while(true) 循环。

      其他人可能会给你一个适合你的已知设计模式的“名称”,但我不知道设计模式的名称。

      【讨论】:

      • 谢谢!我在无限循环中使用 ThreadPool 而不是创建几个线程来使用这种类型的循环的设计怎么样?好点了吗?
      • 假设我理解正确,是的。因此,一个主循环将工作添加到线程池,您让线程池担心线程管理。我知道 .Net 4.0 的通用任务可能适用于此。但是您可能想要搜索特定于线程的“设计模式”。祝你好运,对不起,我帮不上忙。
      猜你喜欢
      • 2011-12-28
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      相关资源
      最近更新 更多