2010-04-03 7 views
5

J'ai écrit une DLL multithread pour l'accès à la base de données en utilisant ADO/ODBC pour une utilisation avec une application héritée. J'ai besoin de garder plusieurs connexions de base de données pour chaque thread, donc j'ai mis les objets ADO pour chaque connexion dans un objet et pense à en conserver un tableau dans un objet threadInfo personnalisé. Évidemment, un vecteur servirait mieux ici - j'ai besoin de supprimer/réorganiser des objets sur le pouce et un vecteur simplifierait cela. Le problème est, j'alloue un tas pour chaque thread pour éviter les conflits de tas et les choses et d'allouer toute ma mémoire à partir de là. Donc, ma question est: comment puis-je faire le vecteur allouer à partir du tas spécifique au fil? (Ou sait-il en interne d'allouer de la mémoire du même tas que sa classe wrapper - cela semble improbable, mais je ne suis pas un gars C++) J'ai cherché un peu sur google et il me semble que je devrais écrire un allocateur ou quelque chose ce qui ressemble à tellement de travail que je ne veux pas. Est-ce qu'il y a un autre moyen? J'ai entendu dire que le vecteur utilise le placement-nouveau pour tous ses trucs à l'intérieur, donc peut-on travailler sur l'opérateur de surcharge?Création d'un vecteur C++ en tant que membre d'une classe utilisant un pool de mémoire

Ma connaissance insuffisante de l'intérieur de C++ n'aide pas, vu que je suis principalement un programmeur C (même que - relativement). C'est très possible qu'il me manque quelque chose d'élémentaire quelque part. Si rien de plus facile ne se présente, j'irai peut-être faire le tableau, mais j'espère que cela ne viendra pas. J'utilise MS-VC++ 6.0 (hé, c'est impoli de rire! :-P).

Toute aide sera grandement appréciée. Comment puis-je attribuer le vecteur à partir du tas spécifique au thread?

Répondre

3

Vous transmettez (au moment de la compilation) un allocateur approprié. Here est un classique sur la façon de le faire. Si vous suivez le conseil de cet article (ou simplement copier le code et l'adapter si nécessaire), pour un programmeur C écrire un allocateur peut être plus facile que d'obtenir la sémantique de copie d'une classe avec un tableau alloué dynamiquement. Notez que, si vous placez des objets dans le vecteur (ou votre propre tableau, FTM), qui utilisent eux-mêmes le tas (chaînes, par exemple), vous devez également prendre en compte qu'ils utilisent votre tas spécial. Pour les conteneurs de la bibliothèque standard (std::basic_string<> est un tel conteneur), c'est facile car vous pouvez également leur transmettre votre allocateur. Pour vos propres types, vous devez vous assurer que vous-même.

Et essayez de vous éloigner de VC6 aussi vite que possible. C'est vénéneux.

+0

Oui, je viendrais là avant. Franchement, ils ont commencé par «ne pas utiliser cela pour surcharger de nouveaux [...] ... il n'y a aucune raison d'utiliser un allocateur dans un code normal» et cela m'a un peu rebuté. Vérification à nouveau, maintenant. Les objets du vecteur utiliseront le tas spécifique, ouais. Je m'en suis déjà assuré. Je ne connaissais pas le modèle de basic_string, alors merci! (Mais en dehors du vecteur, j'ai pris soin de garder tous les membres comme des primitifs.) En attendant, attendez de voir si d'autres réponses se présentent! –

+0

@ Deep-B: Je suppose que devoir mettre un objet sur un tas spécial ne compte plus comme du "code normal", donc ce n'est pas un argument dans votre cas. ':)' Comme pour les chaînes en C++: Il existe une chaîne typedef basic_string (dans l'espace namspace 'std', ou bien sûr) dans l'en-tête' ' de la bibliothèque standard. 'std :: basic_string' a deux autres paramètres de template qui sont par défaut' std :: char_traits 'et' std :: allocator '. Si vous 'typedef std :: basic_string , mon_allocateur > my_string_type' vous avez quelque chose de similaire à 'std :: string', mais en utilisant votre propre tas. – sbi

0

Consulter __declspec

Le code suivant déclare un thread entier variable locale et initialisées avec une valeur:

__declspec(thread) int tls_i = 1; 

Sur une autre note. Ce n'est pas une bonne idée de garder les connexions ADO ouvertes pendant une longue période. Vous rencontrerez beaucoup de problèmes avec la connectivité DB. Ils apparaîtront ouverts à l'application. Cependant, ils vont bombarder avec un message "Erreur réseau générale" lorsque vous envoyez une requête à travers.

Il est préférable de fermer la connexion dès que possible via votre application et de vous fier au pool de connexions géré par le système d'exploitation. En outre, en fonction du nombre de clients connectés à la base de données, vous pouvez atteindre le nombre maximal de sockets ouverts côté serveur. C'est de la mémoire.Une fois qu'une connexion est fermée côté client, la connexion sur le serveur passe dans un état TIME_WAIT. Par défaut, le socket serveur prend environ 4 minutes pour se fermer, il n'est donc pas disponible pour les autres clients pendant cette période. L'essentiel est qu'il y a un nombre limité de sockets disponibles sur le serveur. Garder trop de connexions ouvertes peut créer un problème.

Désolé, nous sommes bien loin du sujet.

+0

Désolé, ne peut pas utiliser - __declspec est: 1> cassé pour les systèmes d'exploitation avant Vista (Vista réellement FIXÉ quelque chose? !!!!); 2> échoue (UB, je pense) si vous appelez les fonctions dll via LoadLibrary(). J'ai déjà décidé d'utiliser les indices TLS après quelques recherches sur ce sujet. ... Et je ne sais pas comment cette réponse est pertinente, vu que je parle d'un objet ... mais merci quand même. –

+0

Désolé, je voulais dire __declspec (thread), pas __declspec. Évidemment. : P –

+0

Hm, malheureusement que (la durée de vie de la connexion) n'est pas entre mes mains. La DLL fournit simplement à l'application existante une interface permettant de lancer des requêtes sur des bases de données qu'il n'a pas d'autre moyen de contacter. Je pourrais cependant mettre vos conseils dans la FAQ sur l'utilisation - pour les gars qui vont réellement coder les programmes des appelants. Merci pour l'info sur les trucs de synchronisation. Il me semble que j'ai besoin de faire plus de recherches ... et de tester la DLL sous une charge vraiment lourde une fois terminée ... –

Questions connexes