2010-09-02 3 views
2

Je veux avoir deux procédures qui peuvent s'appeler l'une l'autre, ou être appelées à partir de n'importe quel threads en cours d'exécution, mais n'en avoir qu'une qui court à la fois. Comment puis-je faire ceci? Est-ce que cela fonctionnera correctement?Puis-je imbriquer des sections critiques? Est-ce que TCriticalSection est emboîtable?

var 
    cs: TCriticalSection; 

procedure a; 
begin 
    cs.Acquire; 
    try 
    // Execute single threaded here. 
    finally 
    cs.Release; 
    end; 
end; 

procedure b; 
begin 
    cs.Acquire; 
    try 
    // Execute single threaded here. Maybe with calls to procedure a. 
    finally 
    cs.Release; 
    end; 
end; 

Répondre

4

Oui, cela fonctionnera. La procédure A peut appeler B et vice versa dans le même thread et pendant que le thread A utilise la procédure A ou B, le thread B doit attendre quand il veut utiliser ces procédures.

Consultez la documentation MSDN sur les sections critiques: http://msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx

sections critiques peuvent être imbriquées, mais pour chaque appel d'acquérir vous devez avoir un appel à la libération. Parce que vous avez votre appel Release dans une clause try .. finally, vous vous assurez que cela arrive, donc votre code est correct.

1

Bien qu'il soit possible sur Windows d'acquérir une section critique plusieurs fois, ce n'est pas possible sur toutes les plateformes, certaines d'entre elles bloqueront la tentative de ré-acquisition d'un objet de synchronisation.

Il n'est pas vraiment nécessaire d'autoriser "l'imbrication" ici. Si vous concevez vos classes correctement, de manière à ce que l'interface publique acquière et libère la section critique, et non les méthodes d'implémentation, et si vous vous assurez que les méthodes d'implémentation n'appellent jamais les méthodes d'interface, vous n'avez pas besoin fonctionnalité. Voir aussi la question de dépassement de pile "Recursive Lock (Mutex) vs Non-Recursive Lock (Mutex)" pour plus de détails sur les mauvais côtés de l'acquisition récursive de mutex/section critique.

+0

Merci. Je suis d'accord qu'il n'y a pas besoin d'imbrication tant que la hiérarchie de classe coïncide avec les choses à verrouiller, ce qui serait normalement le cas avec un bon design, mais pense qu'il serait possible de construire un cas où cela ne se produirait pas. (Mon programme n'en fait pas partie, je triche juste.) – soid

+0

@soid: Mais si vous implémentez le verrouillage via des singletons thread-local, alors il n'y aurait aucun moyen de ré-acquérir la même section critique à partir du même thread . Et chaque cas d'utilisation pourrait encore être mis en œuvre. IMO il n'y a pas de réel (comme dans "il n'y a pas d'autre moyen") besoin de sections critiques récursives. – mghie

+0

@mghie: Cela ressemble à une solution soignée. Je vous remercie. – soid

Questions connexes