2

Zu unserer großen Überraschung fanden wir vor kurzem this. Mit SP1 für Windows 2003 hat Microsoft einen Weg geändert, wie sich kritische Abschnitte verhalten. Frühere Threads, die auf sie zugreifen wollten, wurden in FIFO-Weise bedient. Im Moment werden sie rein "zufällig" serviert.Verhungern von Threads mit Windows 2003 SP2

In unserem Fall hatten wir so etwas wie diese:

// 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); 
} 

So mit neuer Implementierung von kritischem Abschnitt in 2003 SP2 AddToList könnte in Hunger sterben, da es keine guarantie ist, dass sie erwachen wird.

Dieses Beispiel ist ein bisschen extrem, aber auf der anderen Seite habe ich Millionen Zeilen von Code, die mit der Annahme geschrieben wurden, dass der Zugriff auf kritische Abschnitte serialisiert ist.

Gibt es eine Möglichkeit, diesen neuen kritischen Abschnitt zu deaktivieren?

EDIT: Seit die alte Version nicht mehr möglich ist, denke ich nur an globale Suche & Replace zu ändern {Enter, Leaver} CriticalSection in etwas wie My {Enter, Leave} CriticalSection. Haben Sie Ideen, wie dies umgesetzt werden sollte, so verhält es sich genau wie Pre-SP2-Version?

Antwort

1

Leider haben Sie ein Problem. Was Sie getan haben, schreiben Sie Ihren Code abhängig von einem Implementierungsdetail und nicht von der Spezifikation.

EnterCriticalSection wurde immer dokumentiert, um keine bestimmte Reihenfolge zu garantieren, dass Threads den Abschnitt erwerben, aber die Tatsache, dass sie dies in einer FIFO-Weise in älteren Versionen des Betriebssystems getan haben, ist das, worauf Sie basieren herumcodieren.

Der Weg, diese neue Art des Verhaltens zu deaktivieren, besteht nicht darin, SP1 zu installieren.

Jetzt, nachdem ich das gesagt habe, glaube ich nicht, dass es nachteilige Probleme mit Ihrem Code geben wird, es sei denn, Sie haben Ihre Threads völlig anders priorisiert. Sicher, eine der beiden Methoden kann den Abschnitt mehr als einmal hintereinander erfassen, obwohl die andere Methode ebenfalls wartet, aber das sollte kein Problem sein.

+1

Es kann tatsächliche Probleme geben. Insbesondere habe ich sie bei einem Legacy-Projekt kennengelernt, bei dem der gesamte Code ohne Threadsafe in einem riesigen kritischen Bereich gesperrt wurde. Man kann sagen, dass es nicht unbedingt ein kritischer Abschnitt gewesen sein sollte, aber dennoch funktionierte es auf XP und brach 2003 ab. Und es war echter Code. – EFraim

+2

Aber wieder, es verließ sich auf Implementierungsdetails und nicht auf die Spezifikation. Wie Sie in Ihrer Antwort geschrieben haben, werden Sperren, wenn möglich, am besten für eine sehr kurze Zeit gehalten. Natürlich wird schlecht geschriebener Code Probleme mit solchen Änderungen haben, daran besteht kein Zweifel. Wie der Artikel in dem von Ihnen geposteten Link beurteilt, sind Thread-Handhabung, Sperren und Planung nicht für den Laien, Sie müssen SEHR sicher sein, dass Sie es richtig machen. "Happens to work" ist vielleicht jetzt gut genug, aber nicht zukunftssicher. –

Verwandte Themen