Голодание потоков с Windows 2003 SP2 - PullRequest
2 голосов
/ 20 июля 2009

К нашему большому удивлению, мы недавно нашли это . С SP1 для Windows 2003 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 году SP2 AddToList может умереть от голода, поскольку нет никаких гарантий, что он будет пробужден.

Этот пример несколько экстремален, но, с другой стороны, у меня есть миллионов строк кода, которые были написаны с предположением, что доступ к критическим секциям сериализован.

Есть ли способ отключить этот новый критический раздел?

РЕДАКТИРОВАТЬ: Поскольку возврат старой версии невозможен, я думаю просто выполнить глобальный поиск и замену, чтобы изменить {Enter, Leaver} CriticalSection на что-то вроде My {Enter, Leave} CriticalSection. У вас есть идеи, как это должно быть реализовано, чтобы оно точно походило на версию до SP2?

Ответы [ 2 ]

1 голос
/ 20 июля 2009

К сожалению, у вас есть проблема. Что вы сделали, так это написали свой код в зависимости от деталей реализации, а не от спецификации.

EnterCriticalSection всегда был задокументирован, чтобы не гарантировать какой-либо конкретный порядок, которым потоки будут получать раздел, но тот факт, что они делали это FIFO-способом, в более старых версиях операционной системы, является тем, что вы основали свой код вокруг.

Способ отключить этот новый способ поведения - не устанавливать SP1.

Теперь, сказав это, я не верю, что с вашим кодом будут неблагоприятные проблемы, если вы не расставили приоритеты в потоках. Конечно, один из двух методов может получить раздел несколько раз подряд, хотя другой метод также ожидает, но это не должно быть проблемой.

0 голосов
/ 20 июля 2009

Это известная проблема: http://www.bluebytesoftware.com/blog/PermaLink,guid,e40c2675-43a3-410f-8f85-616ef7b031aa.aspx К сожалению, похоже, единственный способ состоит в том, чтобы структурировать код так, чтобы он занимал меньше времени в критической секции.

...