2009-10-06 9 views
1

Nous essayons de construire une classe qui fournit le MFC CRecordset (ou, vraiment, la classe CODBCRecordset) sécurité des threads. Tout semble bien fonctionner pour les diverses fonctions comme l'ouverture et le déplacement dans le jeu d'enregistrements (nous joignons ces appels avec des sections critiques), cependant, un problème subsiste, un problème qui semble introduire des blocages dans la pratique.Construction d'un objet C++ (MFC CRecordset) thread-safe

Le problème semble résider dans notre constructeur, comme ceci:

CThreadSafeRecordset::CThreadSafeRecordset(void) : CODBCRecordset(g_db) 
{ // <-- Deadlock! 
} 

L'autre fil peut être un ayant fini dans CThreadSafeRecordset :: Close() malgré nous garde l'appel ci-joint Fermer, mais doesn Pas vraiment d'importance puisque le constructeur est threading ignorant. Je suppose que la classe CRecordset originale est le coupable, faisant de mauvaises choses au moment de la construction. J'ai cherché des techniques de programmation pour contourner ce problème, mais je ne sais pas quelle pourrait être la meilleure solution? Puisque nous n'avons pas de code et que nous ne pouvons pas contrôler d'autres codes dans notre constructeur, nous ne pouvons pas envelopper quelque chose de spécial dans une section critique ...?

Mise à jour: Merci pour l'entrée; J'ai marqué ce que j'ai fini par comme la réponse à ma question. Cela, en combinaison avec le renvoi d'un shared_ptr en tant qu'instance renvoyée pour faciliter la mise à jour du code existant sans traitement du thread.

Répondre

2

Vous pouvez rendre le constructeur CThreadSafeRecordset privé, puis fournir une méthode de fabrique publique qui participe à votre verrouillage et renvoie une instance.

1

S'il n'est pas possible de faire en sorte que CODBCRecordset déplace ses opérations thread-unsafe du constructeur (constructeur par défaut suivi d'un appel Initialize(), par exemple), vous pouvez toujours utiliser composition au lieu d'héritage. Laissez CThreadSafeRecordset être un wrapper autour de CODBCRecordset au lieu d'une sous-classe de celui-ci. De cette façon, vous pouvez explicitement construire votre jeu d'enregistrements quand vous le souhaitez, et le défendre avec la rigueur qui convient. L'inconvénient, bien sûr, est que vous devrez envelopper chaque méthode CODBCRecordset que vous souhaitez exposer, même ceux qui ne se rapportent pas à vos garanties de thread. Une macro C dans le fichier cpp (de sorte qu'il ne peut pas échapper et affliger vos clients) peut aider.