我有一个静态的对象列表。在程序期间,创建了许多线程。创建每个线程后,它立即创建一个新对象,并将其添加到静态列表中。程序中有另一个线程,负责遍历静态列表。
假设一个具有低优先级“A”的线程正在访问该列表,而另一个具有较高优先级“C”的线程也请求访问它,May(确实在极少数情况下),具有中等优先级“B”的线程也存在于系统中,将获得'A'的CPU时间。因此,'C' 将等待'B',这与常识相反。
如何在不涉及此优先级反转问题的情况下锁定列表?
'Lock()' 函数可以提供帮助吗?
谢谢!
我有一个静态的对象列表。在程序期间,创建了许多线程。创建每个线程后,它立即创建一个新对象,并将其添加到静态列表中。程序中有另一个线程,负责遍历静态列表。
假设一个具有低优先级“A”的线程正在访问该列表,而另一个具有较高优先级“C”的线程也请求访问它,May(确实在极少数情况下),具有中等优先级“B”的线程也存在于系统中,将获得'A'的CPU时间。因此,'C' 将等待'B',这与常识相反。
如何在不涉及此优先级反转问题的情况下锁定列表?
'Lock()' 函数可以提供帮助吗?
谢谢!
在使用线程优先级来选择下一个要调度的线程的操作系统上,优先级反转是一个非常普遍的问题。像 Windows。操作系统线程调度器对此有特定的对策,当它检测到倒置问题时,人为地提高线程优先级,从而允许低优先级线程运行并有机会释放锁。描述该功能的 MSDN 页面位于此处。更详细的旧知识库文章在这里。
不要帮忙。
也就是说,最坏的情况是短期优先级倒置问题。当然,除非低优先级线程 A 持有锁很长时间。线程 C 无法取得进展,因为它正在等待锁。正如 Hans Passant 在他的回答中所说,线程调度程序检测到这个问题并提高较低优先级线程的优先级,以便它可以释放锁。他发布的第一个 MSDN 链接很好地解释了这一点。
如果您的低优先级线程 A 持有锁很长时间(即它正在对列表进行复杂的计算)并且这导致您的应用程序出现问题,那么您可以执行以下操作之一:
无论如何,问题不在于锁。问题在于对程序进行编码,以便高优先级线程可以在低优先级线程需要独占访问的数据结构上等待很长时间。