【问题标题】:.Net 4.0 Parallel Programming - how to write data to concurrent collections?.Net 4.0 并行编程 - 如何将数据写入并发集合?
【发布时间】:2010-09-17 18:25:16
【问题描述】:

我有一个网格,定义为:List<List<Cell>>,其中“Cell”是我的自定义类。 我的程序有几个线程可以访问网格上的各种坐标,并更改“Cell”类中的数据。但我只希望一个线程一次将数据写入“Cell”对象。 我认为使用 ConcurrentBag 等并发集合会有所帮助,但似乎所有并发集合都只有添加项目或从集合中删除项目的方法。似乎没有一种线程安全的方式来更改此类集合中保存的数据。

我在这里遗漏了什么,还是没有“简单的方法”来使用这样的集合?

【问题讨论】:

    标签: c# .net-4.0 parallel-processing concurrent-programming concurrent-collections


    【解决方案1】:

    您可以简单地使用互斥锁来对单元格内容进行线程安全访问。它的工作原理是这样的:

    class Cell{
    
     private static Mutex mut = new Mutex();
    
        private static void SetResource(...)
        {
            // Wait until it is safe to enter.
            mut.WaitOne();
    
            //change cell contents here...
    
            // Release the Mutex.
            mut.ReleaseMutex();
        }
    
       }
    

    更多详情请见http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx

    【讨论】:

      【解决方案2】:

      你读过这篇论文吗?

      Thread-safe Collections in .NET Framework 4 and Their Performance Characteristics

      使用ConcurrentBag的示例代码:

      if (bag.TryTake(out node))
      {
          for (int i = 0; i < node.Children.Count; i++)
          {
              bag.Add(node.Children[i]);
          }
      
          ProcessNode(node); //e.g. a short string comparison
      }
      

      你也可以看看ConcurrentDictionary’s support for adding and updating

      【讨论】:

        【解决方案3】:

        并发集合旨在作为一种安全修改集合本身的手段;不是项目。您必须将自己的同步原语添加到Cell 类。如果外部和内部List 实例本身保持不变,则无需对它们应用同步。

        你提到你会有很多读者,但只有一个作者。这是一个非常重要的细节。这意味着任何无锁同步策略都变得非常容易实现。但是,我不鼓励沿着这条路线走,因为它仍然很难做到正确。但是,这也可能意味着ReaderWriterLockSlim可能lock表现更好。

        您必须对这两种方法都进行试验,看看哪一种能在可维护性和效率之间取得最佳平衡。我的预感是你会发现传统的lock 尽管有多个阅读器和一个编写器,但它的性能会更快,但它值得测试。输入代码时,手指肯定会轻松很多。

        这是两者的示例代码。

        public class Cell
        {
          private object m_LockObject = new object();
        
          public object ReadMyState()
          {
            lock (m_LockObject)
            {
              // Return the data here.
            }    
          }
        
          public void ChangeMyState()
          {
            lock (m_LockObject)
            {
              // Make your changes here.
            }    
          }
        }
        

        public class Cell
        {
          private ReaderWriterLockSlim m_LockObject = new ReaderWriterLockSlim();
        
          public object ReadMyState()
          {
            m_LockObject.EnterReadLock();
            try
            {
              // Return the data here.
            }
            finally
            {
              m_LockObject.ExitReadLock();
            }
          }
        
          public void ChangeMyState()
          {
            m_LockObject.EnterWriteLock();
            try
            {
              // Make your changes here.
            }
            finally
            {
              m_LockObject.ExitWriteLock();
            }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-05
          • 1970-01-01
          • 1970-01-01
          • 2017-09-17
          • 1970-01-01
          • 2018-01-26
          • 1970-01-01
          • 2019-05-20
          相关资源
          最近更新 更多