2010-04-03 14 views
5

He estado escribiendo un archivo DLL de subprocesos múltiples para acceso a la base de datos utilizando ADO/ODBC para usar con una aplicación heredada. Necesito mantener múltiples conexiones de bases de datos para cada hilo, así que coloqué los objetos ADO para cada conexión en un objeto y pienso en mantener una matriz dentro de un objeto threadInfo personalizado. Obviamente, un vector serviría mejor aquí: necesito eliminar/reorganizar objetos sobre la marcha y un vector simplificaría eso. El problema es que estoy asignando un montón para cada hilo para evitar la contención del montón y esas cosas y asignar toda mi memoria desde allí.Poner un vector C++ como miembro en una clase que usa un grupo de memoria

Así que mi pregunta es: ¿cómo hago que el vector se asigne desde el montón específico de subprocesos? (O sabría internamente asignar memoria del mismo montón que su clase contenedora - suena improbable, pero no soy un tipo C++) He buscado en Google un poco y parece que podría necesitar escribir un asignador o algo así - que parece tanto trabajo que no quiero ¿Hay alguna otra manera? He oído que el vector usa la ubicación nueva para todas sus cosas internas, ¿así que se puede trabajar en la sobrecarga del operador nuevo?

Mi escaso conocimiento del interior de C++ no ayuda, ya que soy principalmente un programador de C (incluso eso, relativamente). Es muy posible que me esté perdiendo algo elemental en alguna parte. Si no aparece nada más fácil, podría ir y hacer lo de la matriz, pero ojalá no llegue a eso.

Estoy usando MS-VC++ 6.0 (hey, ¡es grosero reír! :-P).

Cualquier ayuda será muy apreciada.

Respuesta

3

¿cómo hago que el vector se asigne desde el montón específico de subprocesos?

Usted pasa (en tiempo de compilación) un asignador adecuado. Here es un clásico sobre cómo hacerlo. Si sigues el consejo de ese artículo (o incluso solo copias el código y lo adapta donde sea necesario), para un programador en C escribir un asignador puede ser más fácil que corregir la semántica de una clase con una matriz dinámicamente asignada.

Tenga en cuenta que, si coloca objetos en el vector (o su propia matriz, FTM), que a su vez usan el montón (cadenas, por ejemplo), debe tener en cuenta que también usan su montón especial. Para los contenedores de la biblioteca estándar (std::basic_string<> es un contenedor de este tipo) es fácil ya que también puede pasarles su asignador. Para tus propios tipos, tienes que asegurarte de eso.

Y trate de alejarse del VC6 lo más rápido posible. Es venenoso

+0

Sí, ya me había topado con esto antes. Francamente, comenzaron con "no usar esto para sobrecargar nuevo [] ... no hay razón para usar un asignador en un código normal" y eso me desanimó. Comprobándolo de nuevo, ahora. Los objetos en el vector usarán el montón específico, sí. Ya me he asegurado de eso. No sabía sobre la plantilla de basic_string, ¡así que gracias! (Aunque aparte del vector, he tenido cuidado de mantener a todos los miembros como primitivos). Mientras tanto, ¡esperando a ver si aparece alguna otra respuesta! –

+0

@ Deep-B: Supongo que tener que poner el objeto en un montón especial ya no cuenta como "código normal", así que eso no es un argumento en su caso. ':)' En cuanto a las cadenas en C++: Hay un 'typedef basic_string string' (dentro de namspace' std', o supuesto) en el encabezado '' de la biblioteca estándar. 'std :: basic_string' tiene dos parámetros de plantilla más que por defecto son' std :: char_traits 'y' std :: allocator '. Si 'typedef std :: basic_string , my_allocator > my_string_type' tienes algo similar a' std :: string', pero usando tu propio heap. – sbi

0

Busque declspec

El siguiente código declara una variable local de hilo entero y lo inicializa con un valor de:

__declspec(thread) int tls_i = 1; 

En otra nota. No es una buena idea mantener las conexiones ADO abiertas durante mucho tiempo. Te enfrentarás a muchos problemas con la conectividad de db. Aparecerán abiertos a la aplicación. Sin embargo, se bombardearán con un mensaje de "Error general de red" cuando envíe una consulta.

Es mejor cerrar la conexión lo antes posible a través de su aplicación y confiar en la agrupación de conexiones gestionada por el sistema operativo.

Además, dependiendo de la cantidad de clientes que se conectan a la base de datos, puede pulsar la cantidad máxima de sockets abiertos en el lado del servidor. Esto es de memoria.Una vez que se cierra una conexión en el lado del cliente, la conexión en el servidor entra en un estado TIME_WAIT. De forma predeterminada, el socket del servidor tarda aproximadamente 4 minutos en cerrarse, por lo que no estará disponible para otros clientes durante ese tiempo. La conclusión es que hay un número limitado de sockets disponibles en el servidor. Mantener demasiadas conexiones abiertas puede crear un problema.

Lo siento, me salí del tema.

+0

Lo siento, no puedo usar eso - __declspec es: 1> roto para el sistema operativo antes de Vista (Vista realmente FIJO algo? !!!!); 2> falla (UB, creo) si llama a las funciones dll a través de LoadLibrary(). Ya he decidido usar índices de TLS después de algunas investigaciones sobre esto. ... Y no estoy seguro de cómo esta respuesta es pertinente, ya que estoy hablando de un objeto ... pero gracias de todos modos. –

+0

Lo siento, quise decir __declspec (hilo), no __declspec. Obviamente. : P –

+0

Hm, lamentablemente eso (la duración de la conexión) no está en mis manos. El DLL simplemente le da a la aplicación heredada una interfaz para disparar consultas en bases de datos que no tiene otra forma de contactar. Sin embargo, podría poner su consejo en las preguntas frecuentes de uso, para los chicos que van a codificar los programas de la persona que llama. Gracias por la información sobre el tiempo. Parece que necesito investigar un poco más ... así como probar el dll bajo una carga realmente pesada una vez que haya terminado ... –

Cuestiones relacionadas