Memcache

Memcache es un sistema para almacenamiento de objetos en memoria que pueden ser solicitados por varios procesos, incluso en distintas máquinas y que actúa como caché para acelerar estas peticiones. Memcache ha sido diseñado de manera genérica aunque su mayor utilidad y para la que fue desarrollado inicialmente es para reducir la carga en sitios web debido a las solicitudes a base de datos que en muchos casos son innecesarias.

    Memcache ha sido desarrollado por Danga Interactive para livejournal en primera instancia pero luego liberado bajo licencia BSD. Hoy en día es empleado por muchos otros sitios webs debido a su gran utilidad, entre ellos: Livejournal, Slashdot, Wikipedia, SourceForge, FotoLog y un largo etc.

    El funcionamiento de memcache es de concepción muy sencilla. En lugar de acceder a la base de datos para solicitar determinada información primero se accede a memcached (el servidor de memcache) a través de tcp/ip (así se puede acceder a servidores memcache en máquinas remotas o en local). Si este tiene la información la devuelve y si no debemos hacer la petición a la base de datos e introducir los datos en memcached para que puedan ser accedidos directamente la próxima vez que los necesitemos. Además cada dato introducido en memcached tiene un tiempo de expiración, tras pasar este tiempo almacenado en el servidor este se considera descartable y se borra del servidor, dejando espacio para otros objetos.

    De una manera muy sencilla también es posible emplear varios servidores memcache, creando una cache distribuida todavía más eficiente o incluso utilizar varios niveles de caché entre máquinas locales y/o remotas.

    Memcaché está basado en libevent una librería de notificación de eventos asíncrona que permite ejecutar callbacks cuando un determinado evento es disparado (además de eventos puede reaccionar a señales o a intervalos de tiempo específicos, más adelante quizás le dedique un post a esta librería).

    Para instalar memcached en nuestro servidor debemos bajarnos las fuentes del sitio de Danga Interactive. La compilación e instalación no debería ser complicada. También es posible descargar fuentes y binario con apt-get o con el gestor de paquetes que tengamos instalado (absténganse windowzers)

apt-get install memcached

 El servidor memcached tiene unas pocas opciones en la línea de argumentos, estos son:

-d (implicito)
-v (verbose)
-vv (más verbose)
-m (memoría en megas disponible para el demonio)
-p (puerto a la escucha, por defecto 11211
-u (usuario bajo el que se ejecuta el servidor)
-l (IP de la que se espera conexiónes, es la única medida de seguridad del servidor, el valor por defecto es escuchar comunicaciones desde cualquier ip lo cual es completamente inseguro si no se está detrás de un firewall)
-c (número máximo de conexiones simultaneas)
-k (activa bloqueos)
-M (devuelve error cuando la memoria se agota)
-r (limita los core dump)

 El demonio toma toda la memoria especificada por el parámetro -m al principio y cuando no puede alamacenar más datos desecha aquellos accedidos menos recientemente (si no se le pasa el parámetro -M)

Ejemplo:
# memcached -d -m 2048 -l 10.0.0.40 -p 11211

El comando anterior iniciará el servidor usando 2GB de memoria y escuchando conexiones desde la ip 10.0.0.40 al puerto 11211. Recordemos que es posible iniciar más servidores memcache en la misma máquina.

Existen disponibles diversas APIs para conectarse al servidor escritas en diferentes lenguajes: PHP, Python, PERL, Ruby, Java, C, C#

Ejemplo en php de conexión con el servidor memcached:

connect(‘localhost’, 11211) or die (“Could not connect”);

$version = $memcache->getVersion();
echo “Server’s version: “.$version.”
\n”;

$tmp_object = new stdClass;
$tmp_object->str_attr = ‘test’;
$tmp_object->int_attr = 123;

$memcache->set(‘key’, $tmp_object, false, 10) or die (“Failed to save data at the server”);
echo “Store data in the cache (data will expire in 10 seconds)
\n”;

$get_result = $memcache->get(‘key’);
echo “Data from the cache:
\n”;

var_dump($get_result);

?>

Alloca

La función alloca reserva espacio en la pila de la función que lo llama, devolviendo un puntero ha este espacio reservado. Este espacio temporal es automáticamente liberado cuando la función que llama a alloca retorna.

Esta es la firma o prototipo de la función:

void *alloca(size_t size);

Su declaración está en el archivo de cabecera alloca.h. El parámetro que se le pasa es el número de bytes que se desean reservar. Alloca además devuelve un puntero nulo cuando no tiene éxito al reservar memoria.

Alloca presenta una serie de ventajas con respecto a malloc a la hora de reservar memoria. Alloca no produce segmentación en los bloques de memoria reservados, ya que el espacio se reserva en la pila. Alloca apenas malgasta espacio y es bastante rápido. Cuando la función que llama a alloca es abandonada la memoria es liberada evitando posibles memory leaks. Esto también ocurre en caso de error en la función, la memoria es liberada de inmediato.

Ejemplo de función que emplea alloca:

int open2(char \*str1, char \*str2, int flags, int mode)
{
char \*name = (char \*) alloca (strlen (str1) + strlen (str2) + 1);
stpcpy (stpcpy (name, str1), str2);
return open(name, flags, mode);
}

Para tener un código similar empleando sólo malloc y free debemos escribir:

int open2 (char \*str1, char \*str2, int flags, int mode)
{
char \*name = (char \*) malloc (strlen (str1) + strlen (str2) + 1);
int desc;
if (name == 0)
fatal (“virtual memory exceeded”);
stpcpy (stpcpy (name, str1), str2);
desc = open (name, flags, mode);
free (name);
return desc;
}

Alloca, sin embargo, también tiene algunas desventajas:

Si intentas reservas más memoria de la que la máquina puede reservar no obtendrás un mensaje de error claro. En su lugar tendrás una señal fatal como las obtenidas en un recursion infinita; probablemente una violación de segmento.

Algunos sistemas no-GNU no tienen soporte para alloca, convirtiendo a alloca en menos portable. Sin embargo hay algunas implementaciones en C para solventar estas deficiencias en estos sistemas.

Sigue este link para saber más de reserva de memoria

Obstack

Obstack es otros de los medios que emplea la librería C de GNU para la asignación dinámica de memoria. Obstack es una pila de objetos (datos) que puede crecer dinámicamente. Es posible crear cualquier número de obstacks para, en cada uno, ir almacenando diferentes conjuntos de datos. En cada obstack el último objeto en entrar es el primero en salir.

    Obstack es pues otro de los métodos de la librería glibc para la reserva dinámica de memoria.

    A parte de esta limitación en el orden de almacenaje obstack es capaz de contener cualquier número de objetos de cualquier tamaño. Obstack está implementado con macros, de manera que la asignación de espacio es muy rápida si los objetos son pequeños. La única sobrecarga por objeto es el relleno necesario para colocar un objeto en unos límites adecuados.

    Para la creación de un obstack debes primero incluir el archivo de cabecera obstack.h. En este archivo se declara la estructura obstack de tamaño fijo y que registra el estado del obstack y como encontrar el espacio donde los objetos están localizados. No se debe intentar acceder al contenido de esta estructura directamente sino que se debe utilizar las funciones diseñadas especificamente para obstack.

    Obstack puede ser tratado como cualquier otro tipo de objetos, puedes crear obstack dinamicamente o crear obstacks que contengan a su vez otros obstacks.

    Todas las funciones que trabajan con obstacks necesitan que se les especifique el obstack a usar. Se hace esto a través de un puntero a la estructura de tipo struct obstack* .

    Los objetos dentro del obstack son empaquetados en bloques llamados chunks. La estructura obstack apunta a una cadena de chunks actualmente en uso.

    La librería obstack obtiene un nuevo chunk cada vez que debe insertar un nuevo objeto que no cabe en un chunk anterior. La librería administra automáticamente estos chunks de manera que no hay que prestarles demasiada atención, pero hay que propocionar una función a la librería obstack para que esta se haga con un nuevo chunk. Generalmente se debe proporcionar un a función que emplea malloc directa o indirectamente. También se debe proporcionar una función que libere el chunk (free).

Ejemplo:

#include //declara todas las variables, funciones y macros necesarios para obstack

//Estas dos macros definen los métodos para la generación de memoria dinámica y su liberación
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free

//función que se llamara en el caso de error en la reserva dinámica de memoria
void my_obstack_alloc_failed(void)
{

}

//Declaramos nuestra estructura obstack
static struct obstack myobstack;

//La inicializamos
obstack_init(&myobstack);

//Declaramos que función será llamada en caso de error al reservar memoria dinámica
obstack_alloc_failed_handler = &my_obstack_alloc_failed;

//Grabamos en nuestro obstack la cadena “hola mundo”
obstack_alloc(“hola mundo”,11);

Para almacenar un bloque con un contendio específico utilizamos la función obstack_copy

void* obstack_copy (struct obstack* obstack-ptr, void* address, int size)

La función obstrack_copy0 además agrega un caracter nulo (ascii 0) al final.

void* obstack_copy0 (struct obstack* obstack-ptr, void* address, int size)

En el último argumento size no debemos tener en cuenta este carácter nulo extra. Ejemplo:

char*
obstack_savestring (char* addr, int size)
{
return obstack_copy0 (&myobstack, addr, size);
}

    Para liberar objetos en el obstack se emplea obstack_free

void obstack_free (struct obstack* obstack-ptr, void* object)

    Si objeto es un puntero nulo, todo lo almacenado en obstack será liberado. Cualquier otro valor debe ser un puntero a un objeto del obstack. Ese objeto será liberado y todos los que se encuentran a continuación de él.

    Observa que si object es un puntero nulo, el resultado será un obstack no inicializado. Para liberar todos los objetos del obstack pero dejando el obstack válido para agregar nuevos objetos tenemos que pasarle como object el primer objeto almacenado.

    Recuerda que obstack está agrupado en chunks. Si se liberan todos los objetos de un chunk, obstack automaticamente liberará este chunk para que pueda ser utilizado como recurso para otros elementos del programa.

    Recordemos que los interfaces definidos en obstack pueden estar definidos como funciones o como macros. Ejemplo:

char* x;
void* (\* funcp) ();
/\* Use the macro. \*/
x = (char* ) obstack_alloc (obptr, size);
/\* Call the function. \*/
x = (char* ) (obstack_alloc) (obptr, size);
/\* Take the address of the function. \*/
funcp = obstack_alloc;

    Si empleas otro compilador que no sea el de GNU debes tener esto en cuenta.

Para saber más:


GNU C Library Obstacks

Realloc y calloc

Como ya habiamos comentado en un anterior post sobre la asignación de memoria dinámica además de malloc que asigna un zona de memoria para nuestra programa tanto realloc como calloc hacen exactamente lo mismo pero además tienen capacidades adicionales (que las hacen maś caras computacionalmente hablando, así que si no necesitas ninguna de estas características utliliza directamente malloc. Sino estarás malgastando recursos).

La función calloc cuya firma o prototipo es la siguiente:

void* calloc(size_t nmemb, size_t size);

Inicializa la zona de memoria reservada. Como se puede observar sus argumentos son diferentes de las de la función malloc que sólo recibía el número de bytes a reservar. Para calloc es necesario dar el número de elementos a reservar y el tamaño de cada uno de esos elementos. Así tenemos que por ejemplo:

int* pi;
pi = calloc(50,sizeof(int));

Reservará espacio para 50 enteros asignando al puntero pi la dirección en memoria del primero.

La función realloc por otra parte intenta cambiar el tamaño de una zona de memoria previamente asignada dinamicamente copiando, si es posible, su contenido anterior.

Esta es su firma:

void* realloc(void* ptr, size_t size);

Si el cambio de tamaño no se puede llevar a cabo entonces la función devolverá un puntero a null

ip = (int* ) realloc ( ip, 25*sizeof(int) );

Siguiendo el primer ejemplo este redimensionará la zona de memoria asignada por la función calloc. Debemos tener en cuenta que esta función puede modificar además el valor del puntero. Recolocando la zona de memoria reservada en otra zona de la memoria de la máquina dependiendo de la situación. Incluso una disminución en el tamaño de la memoria puede dar lugar a una recolocación del segmento de memoria.

Como con malloc y calloc toda memoria reservada dinámicamente debe ser liberada con free.

void free(void* ptr);

Esperanza Aguirre podría presentarse a la presidencia del PP

La presidenta de la Comunidad Autónoma Madrileña, Esperanza Aguirre, podría presentarse al congreso que su partido va a celebrar el próximo mes de junio en Valencia para elegir al próximo presidente del PP.

Los últimos movimientos y noticias en el seno del PP está claro que son tomas de posicionamiento de cara a esta posibilidad que aparecía una y otra vez en los medios de comunicación. Aguirre está comprobando sus posibilidades a viva cuenta de que su archienemigo Luis Gallardón, alcalde de Madrid podría ocupar un nuevo cargo de enorme responsabilidad dentro del partido.

Esto se pone interesante y estoy deseando que Esperanza se presente, imagínate que celebrasen debates Rajoy – Aguirre uno en Telecinco y otro en la COPE. ¿Sobre que niña hablará ahora Rajoy?

Reserva de memoria en glibc

Glibc proporciona varias funciones para reservar memoria bajo el control explícito del programa. Cada una de estas funciones varían en cuanto a eficiencia:

  • La familia de funciones malloc permite una reserva de memoria completamente genérica.
  • Obstack es otra familia de funciones menos genérica pero más eficiente para reservar memoria tipo pila.
  • Y la función alloca te permite reservar espacio de almacenamiento dinámicamente que será liberada automáticamente.
  • Las funciones tipo malloc son las más empleadas debido a su versatilidad (aunque haya que pagar un coste en eficiencia). Está es la firma de la función malloc

    void *malloc(size_t number_of_bytes);

    Su empleo es muy sencillo, si quieres reservar digamos 300 bytes debes pasarle ese número como parámetro y la función, en caso de éxito, te devolverá un puntero al comienzo de esa zona de 300 bytes reservada para ti. En caso de error devuelve un puntero a NULL (generalmente debido a una falta de memoria). El puntero a void, el tipo del valor de retorno, simplemente nos permite, mediante un cast (implicito), emplear cualquier tipo de datos para su almacenamiento. El tipo size_t es simplemente un unsigned int definido en varios archivos de cabecera stdio.h, stddef.h, stdlib.h, and string.h:

    typedef unsigned int size_t;

    por ejemplo

    char *micadena;
    micadena = malloc(200);

    Intentará hacer que el puntero micadena apunte al comienzo de una zona reservada para ti de 200 bytes o retornando un puntero a null en caso de fallo.

    El operador sizeof (atención no es una función aunque lo parezca) se utiliza muy a menudo en conjunción con malloc ya que este nos devuelve el número de bytes que ocupa un determinado tipo de datos que se le pasa como argumento, así:

    sizeof(int);
    sizeof(char);
    sizeof(miEstructura);

    Nos devolverá el tamaño que ocupa en bytes un entero un caracter o una estructura definida por nosotros respectivamente. Siguiendo nuestro ejemplo para reservar espacio para una cadena de 200 caracteres la forma más correcta tras todo esto sería:

    char *micadena;
    micadena = malloc(sizeof(char)*200);
    if(!micadena)
    {
    printf(“Error fatal. No hay suficiente memoria\n);
    }

    sizeof puede ser usado para encontrar el tamaño de cualquier tipo de datos, variables o estructuras. Simplemente debes proporcionale uno de estos como argumento. Pongo otro ejemplo de esto:

    int i;
    struct COORD {float x,y,z};
    typedef struct COORD PT;

    i = sizeof(int);
    i = sizeof(i);
    i = sizeof(struct COORD);
    i = sizeof(PT);

    Todas las lineas anteriores son válidas.

    Una función que si debería estar siempre acompañando a malloc es la función free. Se encarga de liberar la memoria que previamente hemos reservado, su firma es la siguiente:

    void free(void *ptr);

    y el puntero que le debemos pasar como argumento es obviamente el que nos devolvió la función malloc. Un error relativamente común cuando empleamos malloc es no utilizar free para liberar la memoria cuando ya no la necesitamos. Esta es la causa principal de los llamados “memory leaks” o “porque mi programa consume desenfrenadamente más y más memoria”.

    Una nota sobre malloc: malloc NUNCA inicializa el bloque de memoria que acaba de reservar. Si crees por ejemplo que ese bloque debe contener byes a cero estas equivocado, puede contener cualquiera valores (basura).

    Para no hacer este post más extenso comentaré en otro proximamente las funciones realloc y calloc cuyo propósito es idéntico aunque tienen nuevas características (que también los hacen más caros computancionalmente hablando)

    Para saber más:
    Librería C de GNU

Glibc

En este pequeño post haré una pequeña introducción sobre la librería Glibc. Aunque sobradamente conocida su estudio en la mayoría de los casos es muy superficial. Tener al menos una visión global de las rutinas que implementa esta librería desarrollada por GNU es básica en muchos entornos de programación.

Empecemos por el principio y por lo más obvio (es decir, las perogrulladas). Glibc es una librería C que proporciona al lenguaje rutinas básicas de la que este carece. Rutinas para, por ejemplo, la manipulación de cadenas, operaciones de entrada y salida, administración de memoria, búsqueda en directorios y un largo etcétera. Glibc es quizá la librería más importantes en sistemas GNU/LinuxGNU/Hurd y una de las de mayor tamaño. De hecho el compilador gcc agrega por defecto está librería a la hora de iniciar la compilación y enlace de código. glibc significa GNU C Library y contiene todas las librerías especificadas por el estándar ANSI C además de características adicionales especificas de POSIX y otras derivadas de sistemas UNIX y también algunas específicas de sistemas GNU, claro.

Glibc como cualquier otra librería empleada en programas C realmente consiste en 2 partes: ficheros de cabeceras que definen tipos, macros y declaran variables y funciones; y la librería real o archivo que contiene las definiciones de las variables y funciones.

En sistemas GNU/Linux los ficheros de cabecera con todas estas declaraciones se encuentran en /usr/include mientras que la librería en sí está en /lib bajo el nombre libc-{numero-version}.so (libc-2.3.6.so en mi máquina).

Recuerda que en C, una declaración solamente proporciona información de que una función o variable existe y le asigna un tipo. Para una declaración de una función, nos puede dar además información sobre los tipos de sus argumentos. El propósito de las declaraciones es permitir que el compilador procese correctamente referencias a funciones o variables declaradas. Una definición, sin embargo, asigna espacio de almacenamiento para una variable o dice que hace una función.

Para usar las facilidades que nos proporciona librería GNU C, debes asegurarte que las fuentes de tu programa incluyen los archivos de cabecera correctos. De esta manera el compilador tendrá las declaraciones adecuadas y podrá procesar correctamente las referencias a ellas. Una vez que el programa haya sido compilado, el enlazador resolverá estas referencias proporcionadas por el archivo que contiene la librería.

Los archivos de cabecera son incluidos en las fuentes del programa mediante la directiva de preprocesador #include. El lenguaje C soporta dos tipos de directiva, la primera,

#include “header”

típicamente usada para incluir ficheros de cabecera escritos por ti mismo; esto contendrá definiciones y declaraciones describiendo interfaces entre las diferentes partes de una aplicación. Por el contrario,

#include <file.h>

Se emplea para incluir archivos de cabecera que contienen definiciones y declaraciones de una librería estándar. Esta librería normalmente ha sido instalada por el administrador del sistema. Deberías emplear esta segunda forma para añadir los archivos de cabecera de la librería C.

La primera forma buscará la librería en el directorio local, si no se especifica una ruta; y la segunda buscará el fichero de cabecera en el directorio marcado para tal fin dentro del sistema (/lib).

La bandera española ondea en el ayuntamiento de Bilbao

Aunque haya habido protestas, el alcalde de la capital vizcaina dice que con esta medida se ha dado cumplimiento a la sentencia del TSJPV.

El alcalde de Bilbao, Iñaki Azkuna, ha afirmado hoy que la colocación de la bandera española en el Ayuntamiento ha sido acogida con “cierta indiferencia” por los bilbaínos y que “no ha habido ninguna bronca, salvo la esperada” por este motivo.

En rueda de prensa, Azkuna se ha referido a la colocación el pasado viernes de la enseña nacional, junto con la ikurriña, en la fachada consistorial y a la posterior izada de una bandera de Bilbao de dimensiones mucho mayores en la aledaña plaza de Erkoreka.

El primer edil ha señalado que con la primera de estas medidas ha dado cumplimiento a la sentencia del Tribunal Superior de Justicia del País vasco que ordenaba que la bandera española colgara todos los días en el Ayuntamiento.

Azkuna ha asegurado que la posterior colocación de una enseña de Bilbao ha obedecido al “orgullo de los bilbaínos de tener bandera” y a que ésta existe “desde tiempo inmemorial”.

Por otro lado, la izquierda abertzale ha celebrado esta tarde una manifestación contra la “imposición” de la bandera española en el Ayuntamiento.