队列有时会被破坏

时间:2014-06-09 03:38:55

标签: c# .net queue

我正在运行一个繁重的多线程程序并看到一些奇怪的行为。我将首先尝试解释一下架构。

应用程序基本上有一个大小为30的队列数组。数组中的每个队列都由一个线程处理。外部ome外部线程将根据id的mod继续将实体添加到队列数组中。

例如:如果实体id = 100,它将进入100%30 =第10队列

我遇到的问题有时是将id = 100的实体添加到队列中,但处理线程将一个完全不同的实体出列,但属于同一个队列。 ë

例如:外部线程将实体id = 50排入队列,该队列进入第20个队列,但是线程出队并且id = 80的实体

这只发生在生产环境中,无论如何都无法模拟。它很少发生,没有任何类型的触发器,如应用程序重启后。

我怀疑这可能会发生,因为我在排队/出队时没有使用任何锁定导致数据损坏。

想知道是否有人在此之前遇到过类似的问题,或者有任何建议可以避免这种情况。添加锁是前进的方法之一,但我想在确定之前确认问题的根源。

2 个答案:

答案 0 :(得分:5)

  

我怀疑这可能会发生,因为我没有使用任何锁   当排队/出队导致数据损坏时。

是的,它是数据竞赛的来源。如果您的多个线程正在生成并使用常见的,不受保护的数据结构上的对象,那么您描述的效果将随机出现。数据竞争更多地发生在生产中#34;这是典型的,因为您使用更优化的代码,在更快的机器上,并且通常有更多的线程,增加了数据竞争的可能性。

使用锁定机制保护对公共结构的每次访问(例如Monitors)。 MSDN还在Thread Synchronization上提供了多个教程。

最后,正如@Ronan已经提到的那样,请考虑使用System.Collections.Concurrent中的集合:它们的访问权限已经是线程安全的,并且它们针对多线程场景进行了优化,使您的工作变得更加容易。

修改 当性能很重要时,请始终考虑分析两种方法(使用手动保护的集合与来自System.Collections.Concurrent的集合)

答案 1 :(得分:1)

你说你没有使用任何锁,你使用的是Queue类吗?如果是这样,您应该在这些场景中使用ConcurrentQueue类,它位于System.Collections.Concurrent命名空间中