在C#中创建具有优先级继承的互斥锁

时间:2013-03-13 10:07:55

标签: multithreading c#-4.0 mutex

我有一个静态的对象列表。 在程序期间,创建了许多线程。 创建每个线程后,它会立即创建一个新对象,并将其添加到静态列表中。 程序中还有另一个线程负责迭代静态列表。

假设具有低优先级'A'的线程访问该列表,而具有较高优先级'C'的另一个线程也要求访问它,May(在极少数情况下确实如此),具有中等优先级的线程系统中存在的'B'也将获得'A'的CPU时间。 因此,'C'将等待'B',这与常识相反。

如何在不涉及此优先级倒置问题的情况下锁定列表?

“Lock()”功能可以提供帮助吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

优先级倒置是操作系统上的一个非常普遍的问题,它使用线程优先级来选择要调度的下一个线程。像Windows一样。操作系统线程调度程序具有针对它的特定对策,当它检测到反转问题时人为地提高线程优先级,因此允许低优先级线程运行并给予释放锁定的机会。描述功能is here的MSDN页面。旧的知识库文章包含更多详细信息is here

不要帮忙。

答案 1 :(得分:2)

也就是说,在最坏的情况下,短期优先级倒置问题。当然,除非低优先级线程A持有锁定很长时间。线程C无法进行,因为它正在等待锁定。正如Hans Passant在他的回答中所说,线程调度程序检测到这个问题并提升优先级较低的线程的优先级,以便它可以释放锁。他发布的第一个MSDN链接解释得非常好。

如果您的低优先级线程A持有锁很长时间(即它在列表上进行复杂计算)并且这会导致应用程序出现问题,那么您可以执行以下操作之一:

  • 增加主题A的优先级
  • 让线程A锁定列表,获取项目,解锁列表,然后处理项目
  • 锁定列表,制作副本,解锁列表,然后处理副本。
  • 上述
  • 的某些变体或组合

无论如何,问题不在于锁定。问题在于对程序进行编码,以便高优先级线程可以在较低优先级线程需要独占访问权限的数据结构上等待很长时间。