2011-04-27 32 views
3

今天我在MSDN碰到这个传来:临界区的变化在Windows 2003 SP1

“与Windows Server 2003 带有Service Pack 1(SP1)开始,线程 等待一个临界区不 收购的临界区 先来先服务的基础。这 变化增加性能 显著的大多数代码。但是, 一些应用程序依赖于先入 先出(FIFO)顺序和可 执行poo 当前版本的Windows( 示例,使用临界区段作为 速率限制器的 应用程序)。为确保您的 代码继续正常工作,您可能需要添加 同步的其他级别。例如,假设 您有一个生产者线程和一个 消费者线程正在使用 临界区对象来同步 他们的工作。创建两个事件对象, 一个用于每个线程用于通知 它已准备好为其他线程 继续。消费者线程将 等待生产者进入临界 部分之前的信号其 事件,生产者线程将 等待消费者线程进入临界 部分之前的信号 它的事件。 。每个线程离开 临界区之后,它标志着其事件 释放其他线程”

起初,我还以为跆拳道? - 我一直认为线程将收购秩序的一个关键部分他们试图获得它,虽然这似乎是一个服务包行为奇怪的巨大变化,该服务包是针对服务器版的Windows和Vista正在开发当时我相信的时间

无论如何,所以它有点意义 - 这种方式下调度器旋转的下一个等待线程将成为下一个得到关键部分的线程,至少我假设这是唯一的因此,除非他们决定为了好玩而做一个随机选择;)。

不过,这是一个我已经做出的假设,现在正在评估我的代码,以确保没有任何FIFO依赖的情况是一个问题。

有没有人有任何现实世界的问题呢?虽然获取关键部分的线程的顺序不能保证是FIFO,但它通常不是FIFO?如果不是通常是 FIFO(或接近FIFO),有没有人知道一个线程可以等待一个严重竞争的关键部分多长时间?如果它是低优先级的线程,这是否意味着如果始终有更高优先级的线程试图获取临界区(即使低优先级线程很早之前如果遵守FIFO则下一个在线),这是否意味着它可能几乎无限期地等待)?是否有避免这种情况的安全措施,或者是否依赖于授权的辅助同步对象?

当然,这真的只是一个真正严重有争议的关键部分。

我不知道,也许我做得太多了......但有些事情让我困扰。任何见解都会被赞赏。谢谢;)

回答

1

在我的经验,关键部分有从未了FIFO(也许DOC队得到了他们的电线交叉说它在2003年是新的)。是的,它可能导致线程饥饿,我们已经看到很多。如果你需要FIFO,你需要一个互斥锁。

互斥锁是内核对象,因此获取它们比ring 3乐观临界区更昂贵。但是,FIFO并不是你可以(或者应该)必须忽略的那些东西,因为它不是必需的,它不需要与线程的“层次结构”(不管是什么 - 这是否意味着优先级?)有关。 。相同优先级的1000个线程触发单个锁定将很容易导致饥饿。

+0

感谢您的洞察力。我不能评论关键部分是先进先出法,但我一直认为他们是,而且如果他不确定(呃......谁知道),那么文档作者肯定不会写出关于这个'变化'的整段文字。我绝对关心这个问题,这就是我写这篇文章的原因;)。我知道事情会变得多么容易。 – 2017-04-14 09:01:37

1

这是我第一次听到这个,当我想到它时,它似乎不是一个问题。

如果我理解正确的话::

OldWay:

Thread A acquired the CritSec 
Thread B waiting for the CritSec , tried to acquire it at time t 
Thread C waiting for the CritSec , tried to acquire it at time t + dt 

When Thread A releases the CritSec, OS ensures that Thread B acquires it. 

NEWWAY:

Thread A acquired the CritSec 
Thread B waiting for the CritSec , tried to acquire it at time t 
Thread C waiting for the CritSec , tried to acquire it at time t + dt 

When Thread A releases the CritSec, OS may choose any Thread to acquire it. So, it may be Thread B or C that will acquire it after A releases it. 

我从来不认为(不认为任何人假设)的线程等待CritSec将按照他们想要获得它的顺序获得它。

可能出现这种情况对于一些廓/调试器的问题或者一些性能监控机制,使得这一假设...

+0

你真的无法想象这是许多人所做的假设吗?说实话,我可以。也就是说,这种假设的影响是有问题的,并且只会在高负荷下应用。 – 2012-01-27 18:47:55

+0

再次想到,我几乎总是使用相同类型的工作线程来平衡多CPU核心上的工作负载。如果某人有一个分层线程(不是同一类型或同一角色)池,也许这种FIFO行为是需要/期望的... – Malkocoglu 2012-02-07 11:45:54

+0

无论你是否正确,它似乎都是一个静音点。很少依赖于关键部分的顺序,这只是在某些情况下需要注意的事情,特别是如果你有某种级联的关键部分排列起来,我猜(尽管我当然不会)。在这种奇怪而罕见的情况下,FIFO假设的失败可能会导致死锁......至少如果我在想直的话;) – 2012-03-15 03:52:20