使用Windows 2003 SP2进行线程饥饿

时间:2009-07-20 11:58:09

标签: windows-vista windows-server-2008 windows-server-2003 critical-section

令我们惊讶的是,我们最近发现this。对于Windows 2003的SP1,Microsoft改变了关键部分的行为方式。想要访问它们的早期线程以FIFO方式提供。现在,它们以纯粹的“随机”方式提供。

在我们的案例中,我们有这样的事情:

// I now it's kind of ugly design but works
void Class:RunInThread()
{
   while(m_Running)
   {
       EnterCriticalSection(&m_CS);
       DoSomeStuffWithList();
       LeaveCriticalSection(&m_CS);
   }
} 
void Class::AddToList()
{
       EnterCriticalSection(&m_CS);
       AddSomeStuffToList();
       LeaveCriticalSection(&m_CS);
}

因此,随着2003年临界区的新实现,AddToList可能会在饥饿中死亡,因为没有保证它会被唤醒。

这个例子有点极端,但另一方面,我有数百万行的代码,假设对关键部分的访问是序列化的。

有没有办法关闭这个新的关键部分?

编辑:由于无法恢复旧版本,我只想进行全局搜索和替换,将{Enter,Leaver} CriticalSection更改为My {Enter,Leave} CriticalSection。您有没有想过应该如何实现这一点,以便它像SP2之前的版本一样完全

2 个答案:

答案 0 :(得分:1)

不幸的是,你有问题。你所做的是根据实现细节编写代码,而不是编写规范。

EnterCriticalSection一直被记录为不保证线程将获取该部分的任何特定顺序,但事实是它们在旧版本的操作系统中以FIFO方式执行此操作,这是基于代码的基础周围。

关闭这种新行为方式的方法不是安装SP1。

现在,尽管如此,我不相信你的代码会有不利的问题,除非你把你的主题优先顺序区别开来。当然,两种方法中的一种可能会连续多次获取该部分,即使另一种方法也在等待,但这应该不是问题。

答案 1 :(得分:0)

这是一个已知问题:http://www.bluebytesoftware.com/blog/PermaLink,guid,e40c2675-43a3-410f-8f85-616ef7b031aa.aspx不幸的是,唯一的方法似乎是构造代码,使其在关键部分花费的时间更少。