Alphasite

The programmers site

Estadísticas web

Estadisticas web

Publicidad

Languages

Inicio de sesión

Google AdSense

Encuesta

En línea

En este momento hay 0 usuarios y 11 invitados en línea.

Delphi

Safeguards en Delphi.

Introducción


Los safeguards son el nombre que recibe un ingenioso mecanismo que nos permite, en cierto sentido, olvidarnos de los problemas asociados a liberar memoria en Delphi y que simulan de alguna forma el funcionamiento de un recolector de basura. En C++, para aquellos que han trabajado alguna vez con él, este mecanismo se conoce como Smart Pointers.

El truco

El truco para "olvidarnos" de liberar los objetos cuando terminamos con ellos consiste en el uso de interfaces. En delphi los interfaces incorporan un mecanismo de conteo referencial automático. Esto significa que cuando no se van a usar más (por ejemplo cuando salen de ámbito o cuando se "sobreescriben" y no quedan referencias al objeto que implementa dicho interface) se destruyen automáticamente.

Aplicaciones Multihilo en Delphi. Multihilo y el BDE

[series-info:left]

Introducción

Uno de los problemas del multihilo en Delphi se da a la hora de acceder a la base de datos. En Delphi no podemos sencillamente ejecutar el siguiente código desde una tarea por que, probablemente, nos de un error en tiempo de ejecución

procedure MiAccesoABD;
var
  qry : TQuery;
begin
  qry.DatabaseName := 'MiBaseDeDatos';
  qry.Sql.Add('SELECT * FROM Productos');
  qry.Open;
  .
  .  // Más código
  .
end;

Sesiones de base de datos

Esto es debido a que el motor de base de datos (el BDE) no soporta llamadas concurrentes en la misma sesion de la base de datos. Esto quiere decir que, aunque podemos tener tan solo un TDatabase, debemos tener una sola sesion por cada hilo que acceda a la base de datos.

Delegados en Delphi. Pasando metodos y funciones como parametros.

Que es un delegado

Un delegado (de la palabra inglesa delegate) es un prototipo de función es decir, un esquema que debemos seguir al declarar una función. La palabra delegado proviene (o mejor dicho yo la escuche por primera vez) de C# y probablemente en delphi sería más conveniente referirse a ellas como tipos de funciones.

Los delegados se utilizan fundamentalmente para proporcionar tipado al paso de funciones como parametros a otras funciones o metodos.

Para que sirve un delegado

Si alguien ha programado alguna vez en C sabrá que pasar funciones como parametros esta a la orden del día, estas funciones suelen conocerse con el nombre de funciones de CallBack (algo así como "vuelveme a llamar") e implican que tu estás pasando una función como parametro que quieres que sea invocada cuando dicha función tenga unos ciertos datos preparados.

Una buena parte de las funciones de la API de windows funcionan de esta forma, por ejemplo si observamos la ayuda de la función EnumWindows de la API de windows (kernel32.dll):

La funcion EnumWindows enumera todas las ventans de alto nivel de la pantalla pasando el manejador de cada ventana a una funcion de callback definida por la aplicación. EnumWindows ejecuta hasta que la última ventana sea enumerada o hasta que la función de callback devuelva falso.

    BOOL EnumWindows(

    WNDENUMPROC lpEnumFunc,     // pointer to callback function
    LPARAM lParam       // application-defined value
   );

vemos que dicha función recibe dos parametros, uno de ellos siendo un puntero a una función de callback, es decir, una función que será invocada una vez por cada ventana que encuentre la función.

El mundo del runtime en delphi.

Tiempo de diseño y tiempo de ejecución

En Delphi existen dos conceptos que suelen surgir bastante a menudo, tiempo de diseño (design time) y tiempo de ejecución (run time).

El concepto de tiempo de diseño se refiere, de alguna forma, al sistema de diseño del IDE de Delphi, es decir, la parte en la que arrastramos forms, botones, campos de texto, etc ... y los situamos en las posiciones que queremos, es decir, realizamos el diseño de nuestra aplicación.

El tiempo de ejecución se refiere al tiempo durante el cual el programa esta ejecutando, es decir, el tiempo de vida de la aplicación.

Tiempo de diseño vs Tiempo de ejecución

Cuando estamos creando nuestra aplicación, la forma más natural de definir el aspecto de esta ir creando los forms que necesitemos e ir añadiendo botones, campos de texto y otros y situandolos en pantalla hasta encontrar el diseño que buscamos.

Cada vez que creamos un form delphi automáticamente crea una nueva unidad (.pas) y un nuevo fichero de descripción de formulario (.dfm). El IDE de Delphi se encarga de ir modificando estos dos ficheros automáticamente para reflejar los cambios que vamos haciendo. Por ejemplo, vamos a echar un vistazo a un dfm de ejemplo que contiene un Form (Form1) que a su vez contiene un TMemo y TButton.

Aplicaciones Multihilo en Delphi. Primitivas de sincronización de Windows

[series-info:left]

Introducción

En las anteriores partes, en los dos primeros articulos, hemos visto como crear y sincronizar hilos usando las clases predefinidas de Delphi. Estas clases son en realidad un encapsulamiento de las primitivas que nos proporciona windows para el control de hilos de ejecución pero hay determinadas cosas que no se pueden hacer con ellas y debemos recurrir directamente a los servicios que nos proporciona el sistema operativo.

Primitivas de sincronización de Windows

Handles

Las funciones de creación de objetos de windows son bastante similares entre si y tienen la "peculiaridad" de no devolver una instancia del objeto tal y como podemos estar acostumbrados en Delphi sino que devuelve siempre un THandle que no es ni más ni menos que un cardinal. Este cardinal es en realidad el identificador que tiene windows para el objeto que ha creado internamente y que el mismo mantiene.

De esta forma, para aquellos elementos con nombre, podemos acceder a ellos desde cualquier proceso que este ejecutando (no solamente desde los hilos del proceso que lo crea) siempre y cuando tengamos los permisos suficientes (por ejemplo un proceso ejecutando bajo el identificador de un usuario de windows tendrá limitaciones a la hora de acceder a un objeto creado por un administrador).

Aplicaciones Multihilo en Delphi. Los problemas del multihilo

[series-info:left]

Introducción

En los dos artículos anteriores hemos visto una pequeña introducción a la programación multihilo en delphi así como a las funciones de sincronización que Delphi proprociona. Estas funciones de sincronización y el mero hecho de programar usando varios hilos tiene aparejados una serie de problemas a los que deberemos hacer frente si queremos que nuestra aplicación funcione correctamente y sin problemas.

Condición de carrera y exclusión mútua

Una condición de carrera es una situación indeseable en programación y que consiste en que el correcto funcionamiento del programa (o de un segmento del código del programa) depende del orden de ejecución de las tareas.

El problema principal de las condiciones de carrera es que son dificiles de identificar y encontrar y, dado que dos ejecuciones de un mismo programa pueden tener dos planificaciones completamente distintas para sus hilos, muy dificiles de reproducir.

El uso de primitivas de sincronización para todos los datos compartidos nos ha permitido en todo momento evitar situaciones como la siguiente:

Tipos de datos. Tabla Hash.

Introducción

Una tabla hash es una estructura de datos que permite asociar claves con valores y cuya principal ventaja es una complejidad de inserción y busqueda de O(1) (O(n) en el peor de los casos).

Cuando tenemos la necesidad de almacenar datos en memoria tenemos una serie de opciones (listas enlazadas, arrays, arboles...) cada una de las cuales tienes sus ventajas y sus inconvenientes que normalmente consisten en establecer un compromiso entre espacio en memoria y velocidad.

Una lista enlazada aprovecha completamente el espacio de memoria pero la velocidad de busqueda es lineal, para encontrar un elemento debemos ir recorriendo la lista hasta encontrarlo, en un array reservamos toda la memoria que podríamos por adelantado pero por contra obtenemos un rendimiento de busqueda constante O(1). Los arboles constituyen una variación de las listas enlazadas en las cuales se mejora el rendimiento de busqueda (O(log(n))) a cambio de empeorar el rendimiento de inserción.

Tipos de datos. Pipe (o Tuberí­a)

Introducción

Un pipe o tubería es una estructura de datos que representa un canal de comunicación con una estructura de tipo FIFO (primero en entrar, primero en salir).

La denominación de tubería (en ingles pipe) viene del concepto de que los datos que introducimos o empujamos por un extremo de la tubería "aparecen" en el extremo contrario. Si realizamos una operación de lectura en la tubería y no hay datos en esta el hilo llamante se quedará bloqueado hasta que haya datos. Si realizamos una escritura en la tubería y esta ha alcanzado su tamaño máximo el proceso que desea escribir en la tubería se quedará bloqueado hasta que algun lector saque un dato.

Aplicaciones Multihilo en Delphi: Metodos de sincronización de Delphi

[series-info:center]

Introducción

Probablemente la parte más compleja al programar una aplicación con varios hilos es la sincronización entre estos tanto en el acceso a los datos compartidos como en el correcto orden de ejecución que deben seguir.

Uno de los problemas de desarrollar una aplicación multihilo es que son bastante dificiles de depurar puesto que los hilos van entrando y saliendo de ejecución conforme se va acabando su tiempo de ejecución de forma que, al depurar, el depurador va saltando de una linea de código a otra dependiendo de la tarea que vaya estando en la CPU así que siempre hay que tener mucho cuidado al escribir el código por que, si vas a tener que depurarlo, vas a pasarte un buen rato en ello (por no hablar del hecho de que los hilos no tienen porqué, y probablemente no lo haga, ejecutar en el mismo orden y con los mismos tiempos en dos ejecuciones consecutivas).

En esta parte trataremos los objetos de sincronismo más importante que proporciona Delphi mientras que en el siguiente nos centraremos en las primitivas de sincronización que proporciona la API de windows.

Distancia geodésica entre dos puntos

Distancia geodésica

Cuando hablamos de la distancia entre dos puntos solemos referirnos a la distancia en linea recta entre esos dos puntos. Sin embargo cuando queremos calcular la distancia entre dos puntos situados sobre una esfera (en mi caso dos puntos sobre la superficie de la tierra) estamos hablando de la distancia geodésica entre esos dos puntos.

Solo pongo esta función aqui porque en el trabajo necesito calcular la distancia geodésica entre dos puntos y estaba usando una librería COM que era excesivamente lenta para lo que necesitaba (4 milisegundos frente a 1 microsegundo). No tengo ni idea de como funciona lo que pongo debajo (si tengo tiempo lo miraré más detenidamente y trataré de explicarlo (hasta donde yo se consiste en aplicar la formula de la longítud de arco de una circunferencia (aplicando además en este caso una desviación, ff, por el achatamiento de la tierra) dadas la latitud y longitud de cada punto)). La función está adaptada de un código de Visual Basic de Jay Tanner para poder usarla en Delphi.