2

À notre grande surprise, nous avons récemment trouvé this. Avec SP1 pour Windows 2003, Microsoft a modifié le comportement des sections critiques. Les threads précédents voulant y accéder ont été servis de manière FIFO. En ce moment, ils sont servis de manière purement "aléatoire".Familiarisation des threads avec Windows 2003 SP2

Dans notre cas, nous avons eu quelque chose comme ceci:

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

donc avec une nouvelle mise en œuvre de l'article critique en 2003 SP2 AddToList pourrait mourir dans la famine car il n'y a pas guarantie que ce sera réveiller.

Cet exemple est un peu extrême mais d'autre part j'ai millions de lignes de code qui ont été écrites en supposant que l'accès aux sections critiques est sérialisé. Y at-il un moyen d'éteindre cette nouvelle section critique?

EDIT: Étant donné que la récupération de l'ancienne version n'est pas possible, je pense à une recherche globale. & Remplacer pour modifier {Enter, Leaver} CriticalSection en quelque chose comme Ma {Enter, Leave} CriticalSection. Avez-vous des idées comment cela devrait être mis en œuvre afin qu'il se comporte exactement comme comme version pré-SP2?

Répondre

1

Malheureusement, vous avez un problème. Ce que vous avez fait est d'écrire votre code en fonction d'un détail d'implémentation, et non de la spécification. EnterCriticalSection a toujours été documenté pour ne garantir aucun ordre particulier que threads va acquérir la section, mais le fait qu'ils l'ont fait de manière FIFO, dans les anciennes versions du système d'exploitation, est ce que vous avez basé votre code autour.

La façon de désactiver ce nouveau comportement n'est pas d'installer SP1. Maintenant, cela dit, je ne crois pas qu'il y aura des problèmes avec votre code, à moins que vous ayez priorisé vos threads de façon très différente. Bien sûr, l'une des deux méthodes pourrait acquérir la section plus d'une fois de suite, même si l'autre méthode attend également, mais cela ne devrait pas poser de problème.

+1

Il peut y avoir des problèmes réels. En particulier, je les ai rencontrés sur un projet hérité où tout le code non threadsafe a été verrouillé dans une section critique géante. Vous pouvez dire que cela n'aurait pas dû être une section critique en premier lieu, mais tout de même, cela a fonctionné sur XP et s'est cassé sur 2003. Et c'était du vrai code. – EFraim

+2

Mais encore une fois, il s'est appuyé sur les détails de l'implémentation et non sur la spécification. Comme vous l'avez indiqué dans votre réponse, les verrous sont mieux conservés pour une très courte période de temps, si possible. Bien sûr, le code mal écrit aura des problèmes avec de tels changements, cela ne fait aucun doute. Comme en juger par l'article dans le lien que vous avez posté, la manipulation des threads, les verrous, et la planification, n'est pas pour le profane, vous devez être très sûr que vous le faites correctement. "Happens to work" est peut-être assez bon maintenant, mais n'est pas à l'épreuve du futur. –