Archivo para octubre de 2011

Solución del error de caracteres inválidos en el archivo /var/lib/dpkg/available

El archivo /var/lib/dpkg/available es un archivo que usa el sistema de gestión de paquetes dpkg, en GNU/Linux, para instalar y desinstalar software. En este caso se instalan paquetes .deb en Debian, aunque también en otros sistemas operativos derivados de esta distribución, como Ubuntu.

Pero dependiendo de qué repositorios añadas o si instalas y desinstalas muchos paquetes, puede que se produzca un error como este:

dpkg: aviso: analizando archivo «/var/lib/dpkg/available» cerca de la línea 62349 paquete «openshot-ffmpeg»: error en la cadena `Version’ `git-ab0189b-1′: el número de la versión no empieza con un dígito

Para solucionarlo, lejos de editar manualmente el archivo en cuestión (harto arriesgado y, por supuesto, desaconsejado) basta con ejecutar el comando correspondiente de dpkg para limpiar la información de paquetes disponibles:

user@machine:~:$ sudo dpkg --clear-avail

Bastante tiempo llevaba produciéndose en mi equipo, pero como no hace que falle la instalación sino que sólo es un mero aviso, no había llegado a buscar su solución… hasta hoy. Espero que os sirva ;) .

Hal o Win

Hal o Win

Hoy es Halloween; y qué mejor que esta imagen que nada tiene que ver con ello pero que tiene un juego de palabras de los mejores que he visto últimamente. Grande, muy grande. Desde Neoon.

P.D.: Por cierto, la fiesta de Halloween es una fiesta que tiene su origen en la fiesta celta del Samhain y en la fiesta cristiana de Todos los Santos. Por si a alguno se le ocurre decir a estas alturas esto de “yo no celebraré ninguna fiesta traída de EE.UU.”. Por favor, señores, que cada uno celebre lo que quiera ;) .

Qué asco de mundo

[...] en el siglo XXI, tenemos móviles de última generación para hacerle fotos a un cadáver ajusticiado y expuesto públicamente como si estuviéramos en plena Edad Media.

Javier Gallego, periodista de Radio 3, en una entrada sobre el ajusticiamiento de Gadafi y su exposición pública.

Cosa que, por cierto, ya comenté en dos tweets: uno sobre la exhibición en los telediarios del cadáver sin ningún tipo de pudor y otro sobre su ajusticiamiento sin juicio.

Implementación básica de soporte de hilos (threads) usando programación orientada a objetos con C++

Después de este título tan largo viene una pregunta: ¿conocéis alguna implementación de hilos (threads) orientada a objetos en C++ que sea medianamente decente?

Si la respuesta es sí, genial, decídmelo en los comentarios para echarle un vistazo.

Si la respuesta es no, no hagáis como yo y os dediquéis a reinventar la rueda y usad la implementación de hilos de la librería Boost. En serio. Es más, usad Boost para todo lo que podáis porque tiene infinidad de cosas muy buenas y muy útiles ya probadas. De hecho, varias cosas de esta librería fueron incluidas en el último estándar de C++, C++11 (antes conocido como C++0x).

Pero, en caso de que os guste investigar y queráis implementar vuestra propia librería de gestión de hilos mediante programación orientada a objetos en C++, aquí tenéis un ejemplo de lo que a mi se me ha ocurrido (y que, de momento, funciona, claro ;) ). Y es un gran ladrillo, avisados estáis.

Lo primero que hay que saber

Lo primero que —de forma resumida— hay que saber es que la implementación de los hilos depende de cada sistema, aunque hay una especificación POSIX llamada pthreads que tienen implementada la mayoría de los sistemas operativos.

Esta implementación generalmente está hecha en C mediante programación estructurada, con lo que tenemos un conjunto de funciones a la que se le pasan parámetros para controlar todo el funcionamiento de los hilos.

Algunas de estas funciones son la de crear e iniciar el hilo —cuyo parámetro principal es un puntero a la función que dicho hilo tiene que ejecutar—, parar el hilo, esperar a que termine dicho hilo, etc.

De lo que trata esta entrada es de encapsular esta funcionalidad en clases para controlar los hilos mediante programación orientada a objetos y así tener un API más consistente, más abstracta y, sobre todo, más moderna. Y aquí es donde los defensores a ultranza de la programación estructurada empiezan a gritar…

Bueno, yo creo que cada cosa está para lo que está y la programación estructurada está muy bien para programar kernels, pero cuando se trata de programar aplicaciones de usuario por parte de un desarrollador de este tipo de aplicaciones (no de sistemas) siempre es mejor facilitarle la tarea a dicho desarrollador. Y con la POO se consigue.

La idea principal

Como comenté arriba, la idea principal es encapsular las funciones de C de gestión de hilos en clases y métodos de C++. Simple y sencillo ¿no? Para ello, diseñaremos las clases necesarias para incluirlas. En principio sólo una, la clase Hilo; o, mejor, la clase Thread, porque me gusta más programar en inglés, por eso de que si compartes tu código llegarás a más gente en este idioma, nos guste o no.

Pero, antes de nada, hay que solucionar un problema importante: a la función de creación del hilo hay que pasarle como parámetro un puntero a la función a ejecutar, pero las clases en C++ no tienen funciones sino que tienen métodos. ¿Y cuál es la diferencia? La principal diferencia es que en el cuerpo de las funciones se tienen los parámetros que se declaran en su definición mientras que en los métodos, además de los parámetros definidos, se tiene un parámetro oculto llamado, generalmente, this (en C++, self en Delphi…) que es un puntero a la instancia del objeto que llama a dicho método.

Y, obviamente, no se puede pasar un puntero a un método a una función que requiere como parámetro un puntero a una función.

La solución está en pasar un método estático de nuestra clase Thread a esta función pasándole como parámetro (visible, no oculto) el puntero a la instancia de nuestra clase Thread. Luego veremos un ejemplo de implementación.

Después de abordar este problema, lo siguiente es encapsular las funciones de gestión de hilos. Aquí, la verdad, no es más que tener un método en nuestra clase por cada función de gestión de hilos que nos interese gestionar. Simple, la verdad.

Lo que hay que ejecutar

El problema de pasar un puntero a una función en lugar de un método como parámetro de la función de creación del hilo está solucionado. Ahora nos queda qué es lo que hay que ejecutar. Y también es sencillo. Se puede declarar un método en nuestra clase Thread llamado execute() que sea el método estándar que siempre ejecute nuestra clase, aunque una solución más elegante (que no más eficiente, sólo estamos hablando de elegancia) sería implementar el operador () (llamada de función) y ser ese el que ejecute nuestro hilo. Repito, cuestión de elegancia, nada más.

Pero, aquí llegamos al segundo problema: ¿qué pasa si quiero ejecutar código diferente sin tener que modificar mi clase Thread cada vez?

La primera solución que se nos ocurre, por obvia, es la herencia. Declaramos la función execute() (o el operador ()) como virtual y hacemos clases derivadas donde lo implementamos. Sin duda, una muy buena solución.

Pero, ¿y si, por cualquier razón, queremos o necesitamos que nuestro hilo pueda ejecutar cualquier método de cualquier otra clase —siempre y cuando cumpla con una definición de parámetros común—?

Aquí es donde nuestra primera planificación de una sola clase Thread puede no ser suficiente.

La implementación

La solución que se me ocurrió pasa por tener dos clases. La primera, una clase Thread como la del texto anterior donde estén declarados e implementados todos los métodos que vamos a usar para gestionar el hilo, teniendo declarado el método execute() como virtual para que se puedan heredar más clases que implementen dicho método. A esta clase la llamaremos AbstractThread (por no permitir tener instancias de la misma y obligar a que sea derivada).

La otra clase sería una clase que hereda de AbstractThread a la que, ahora sí, llamaremos Thread, pero que tiene la peculiaridad de que va a usar plantillas de C++, también conocidas como templates, para indicar qué método de qué clase se va a ejecutar en el hilo.

Al final, contaremos con dos clases: AbstractThread, que es derivable y que es el método execute() el que ejecutará el hilo, y Thread, que está basada en plantillas y será a través de ellas y de su constructor desde donde indicaremos el método a ejecutar y la clase a la que pertenece.

El pseudocódigo de la interfaz de las clases

En este pequeño snippet de código muestro la interfaz (que no la implementación) básica de las dos clases antes mencionadas. En un principio la clase AbstractThread de la que heredan las demás implementando el método execute() y luego la clase Thread usando plantillas.

Clase AbstractThread


typedef int thread_id;

class AbstractThread {
  private:

    /**
     * Función estática que es la que se le pasa a la función
     * 'pthread_create(...)' para que ejecute. El parámetro
     * 'void* arg' será la instancia de la clase cuya función
     * 'execute()' hay que ejecutar. Un ejemplo de implementación
     * está en el siguiente código.
     */
    static void* thread_entry(void* arg) {
      // Código de ejemplo:
      AbstractThread* thread = reinterpret_cast<AbstractThread*>(arg);
      thread->execute();
      return NULL;
    }

  protected:
    /**
     * Función virtual pura que tienen que implementar las clases
     * derivadas y será la que ejecute el hilo.
     */
    virtual void execute() = 0;

  public:
    /**
     * Constructor de la clase.
     */
    AbstractThread();

    /**
     * Destructor de la clase.
     */
    virtual ~AbstractThread();

    /**
     * Devuelve el identificador del hilo (el 'handle').
     */
    thread_id getId();

    /**
     * Inicia el hilo.
     */
    virtual bool start();

    /**
     * Para el hilo.
     */
    virtual bool stop();

    /**
     * Indica si el hilo se está ejecutando o no.
     */
    bool isRunning();

    /**
     * Pide al hilo que pare de ejecutarse. Este es un método
     * de parada conde la implementación de 'execute()' para
     * de forma cooperativa (sin forzar la parada).
     */
    virtual bool requestStop();

    /**
     * Bloquea el hilo que llama a este método hasta que el
     * hilo en cuestión finaliza (espera la finalización del
     * hilo).
     */
    virtual bool wait();

    /**
     * Similar a 'wait()' pero con un tiempo de espera. Si el
     * hilo no finaliza el dicho tiempo de espera, devuelve
     * un error.
     */
    virtual bool timedWait(int microseconds);

    /**
     * Finaliza el hilo de forma abrupta.
     */
    virtual bool kill(int signum);

    /**
     * Devuelve la prioridad del hilo.
     */
    int  priority();

    /**
     * Fija la prioridad del hilo.
     */
    void  priority(int prio);

    /**
     * Función estática que devuelve el identificador
     * del hilo que llama a esta función.
     */
    static thread_id getCurrentThreadId();

    /**
     * Función estática que hace que el hilo que llama a
     * esta función deje de ejecutarse hasta que vuelva
     * a ser planificado por el kernel.
     */
    static void yield();
};

Clase Thread usando plantillas


template <class Worker>
class Thread : public AbstractThread {
  public:
    /**
     * Tipo de dato nuevo que representa la definición del método
     * a ejecutar en este hilo.
     */
    typedef void (Worker::*WorkerMethod)(const Thread<Worker>* thread);

  private:

    /**
     * Puntero a la instancia de la clase cuyo método hay que
     * ejecutar. En caso de que no se pase ninguna instancia en
     * el constructor, se creará (y destruirá) internamente.
     */
    Worker*      fWorker;

    /**
     * Puntero al método a ejecutar dentro de la clase Worker.
     */
    WorkerMethod fMethod;

  protected:

    /**
     * Método heredado de la clase AbstractThread que se implementa
     * para ejecutar el método del Worker en el hilo.
     */
    virtual void execute() {
      if(fWorker != NULL && fMethod != NULL) {
        (fWorker->*fMethod)(this);
      }
    }
  public:

    /**
     * Constructor de la clase donde se le pasa como parámetro
     * un puntero al método a ejecutar. Como no se pasa instancia
     * de la clase a la que pertenece dicho método, se crea una
     * internamente (y se destruye al final).
     */
    Thread(WorkerMethod method = &Worker::execute);

    /**
     * Constructor de la clase donde se le pasa una referencia a
     * una instancia de la clase de donde hay que ejecutar el método
     * y un puntero al método a ejecutar.
     */
    Thread(Worker& worker, WorkerMethod method = &Worker::execute);

    /**
     * Constructor de la clase donde se le pasa un puntero a
     * una instancia de la clase de donde hay que ejecutar el método
     * y un puntero al método a ejecutar.
     */
    Thread(Worker* worker, WorkerMethod method = &Worker::execute);
};

El resto de métodos de la clase Thread serán los mismos que en la clase AbstractThread por lo que no hace falta volver a implementarlos.

Un ejemplo de uso

Un ejemplo del uso de la clase AbstractThread sería la propia clase Thread, donde basta con implementar el método virtual puro execute() para que sea ese código el que se ejecute en el hilo.

Un ejemplo de uso de la clase Thread podría ser:


#include <iostream>

using namespace std;

class Thread;

class MiClase {
  public:
    void ejecutar(const Thread<MiClase>* thread) {
      // Cualquier código a ejecutar en el hilo, por ejemplo:
      int counter = 5;
      while(counter-- > 0) {
        cout << "Hola mundo." << endl;
        sleep(1);
      }
    }
};

MiClase mi_clase* = new MiClase();
Thread<MiClase>* thr = new Thread<MiClase>(mi_clase,&MiClase::ejecutar);

thr->start();
thr->wait();

delete thr;
delete mi_clase;

Algunas notas acerca del código

En los métodos de las clases AbastractThread y Thread se usan valores de retorno para saber si se han ejecutado correctamente o no. Esta decisión está de mano del desarrollador pudiendo usar valores booleanos, números enteros representando códigos de error (usando, por ejemplo, un enum) o excepciones.

Personalmente, aunque la primera implementación que hice fue devolviendo un tipo de dato enumerado representando códigos de error, creo que la mejor forma de hacerlo es usar excepciones debido a que tienen sus ventajas respecto al uso de valores de retorno.

Clases adicionales necesarias

El uso de hilos en las aplicaciones, además de tener que gestionar correctamente la creación de los mismos, implica, al menos, tres cosas más:

  1. Evitar el acceso a la misma zona de memoria de forma simultánea por dos o más hilos.
  2. Sincronizar el orden de acceso de dos o más hilos a un recurso compartido.
  3. Comunicación entre diferentes hilos.

Es por esto que es necesario implementar otras clases (por seguir con el modelo de programación orientada a objetos) con el fin de tener dichos mecanismos.

Por ejemplo, para envitar el acceso a la misma memoria al mismo tiempo habría que implementar una clase Mutex (mutex viene de mutual exclusion) que evita, precisamente, este supuesto, bloqueando el acceso a ciertas zonas de memoria a todos los hilos en caso de que uno de ellos ya esté en dicha zona.

Además, para la sincronización se debería implementar una clase Semaphore que sirve para indicar el orden en que los hilos acceden a los recursos. Además, también podría servir para pasar información (básica) entre hilos.

Y, finalmente, habría que implementar las clases de comunicación teniendo en cuenta los diferentes métodos que se pueden usar como, por ejemplo, la memoria compartida, colas de mensajes, señales, sockets, colas FIFO

Conclusión

Si estáis implementando aplicaciones en C++ que hagan uso de hilos, como dije más arriba, no os compliquéis la vida y usad la librería Boost. Bien implementada, con una buena interfaz y muy, muy probada.

Pero si, por cualquier motivo, tenéis que implementar vuestra propia librería, bien sea porque queréis aprender o porque no queréis que vuestro programa dependa de otras librerías o porque vuestro jefe os lo ha dicho, podéis probar, si queréis, esta idea que he expuesto aquí y, como no, podéis ponerlo en los comentarios… por compartir más que nada ;) .

Y tened en cuenta que esto es muy mejorable, pero la implementación que he hecho funciona bastante bien y es la que estoy usando actualmente. Espero que os sirva ;) .

X-Men: Primera generación

Carátula de 'X-Men: Primera generación'

X-Men: Primera generación es una película de 2011 de la saga de las películas de los X-Men, precuela de la primera película de dicha saga.

Esta película se ambienta alrededor de los años 60 del pasado siglo (durante la Guerra Fría) con algún flashback adicional a 1944 para contar la historia de los primeros mutantes. La historia se centra en Erik Lehnsherr (Magneto) y Charles Xavier, cómo se conocieron, por qué se hicieron amigos y luego menos amigos (no voy a decir enemigos porque en el resto de las películas se muestra muy bien su amistad).

Además se cuenta la historia de otros personajes de la saga (algunos importantes y otros secundarios) con algunas otras apariciones estelares aunque fugaces.

En general, con las expectativas de que cualquier película de hoy en día es un bodrio, tengo que decir que no, que esta está muy bien hecha y, no sólo eso, sino que tiene una bastante buena historia. Obviamente, los efectos especiales son espectaculares, pero, como he dicho, la historia no desmerece en absoluto y esta te mantiene enganchado a la pantalla durante las dos horas que dura.

Así que, para terminar, en la escala MPSO le doy un 8, recomendando que, si os gusta la saga de los X-Men, no podéis dejar de verla.

No interrumpas

Los que aseguran que es imposible no deberían interrumpir a los que estamos intentándolo.

Thomas Alva Edison (1847 – 1931), empresario y prolífico inventor estadounidense que patentó más de mil inventos y contribuyó a darle, tanto a Estados Unidos como a Europa, los perfiles tecnológicos del mundo contemporáneo (industrias eléctricas, sistema telefónico viable, fonógrafo, películas…).

UNIX es simple

UNIX es simple; sólo es necesario un genio para entender su simplicidad.

Dennis Ritchie (1941 – 2011), científico computacional estadounidense.

Desde aquí mi pequeño homenaje a Dennis Ritchie, verdadero genio de la informática, creador de lenguaje de programación C y, junto con Ken Thompson, del sistema operativo UNIX.

Si, venga, vale. También ha fallecido Steve Jobs y no lo he puesto. La diferencia es que Ritchie revolucionó la informática mientras que Jobs sólo revolucionó la forma en que la gente consume dispositivos (que usan la informática). Y sí, era muy bueno en ello, pero sólo hablamos de dinero. A Dennis Ritchie no le dedicarán portadas de periódicos ni primeras planas en telediarios.

El gigante de hierro

Carátula de 'El gigante de hierro'

El gigante de hierro es una película de animación y ciencia ficción de 1999.

El argumento es que un robot gigante (de hierro, se supone, ¿no? :D ) cae del espacio y un niño de un pueblo lo salva de que se electrocute. A partir de ahí se forja una amistad entre el robot y el niño con las aventuras correspondientes. No destripo más.

Esta película ya la he visto hace bastante tiempo (recomendada por mi amigo Yago) pero quería compartirla porque me parece una de las mejores películas de animación de todos los tiempos. No, quizás, por la calidad de los dibujos, que también la tiene, sino por la calidad de la historia, donde mezclamos la amistad entre el niño y el robot (amistad entre un humano y una máquina, también vista en Terminator 2 y en tantas otras, pero con algunas diferencias) junto con algo más trascendental como es la moral norteamericana ante lo desconocido. El famoso primero dispara y luego pregunta.

Por cierto, el final es muy, muy bueno, aunque si te has fijado en todos los detalles de la película quizás sea un poco predecible. Aún así, repito, es una de mis películas favoritas, por eso en la escala MPSO le doy un 9.

Paul

Carátula de 'Paul'

Paul es una película donde el adjetivo más acertado que la describe es friki. Pero cuando digo friki es muy friki.

La historia: un extraterrestre cuya nave se estrelló en la tierra hace años intenta escaparse de las bases americanas para regresar a casa. Y nada más. Cuatro puntos graciosos y listo. No hay aliciente. De hecho, los diez primeros minutos de la película son soporíferos, donde estás deseando pararla por un lado y continuar por otro para ver si realmente mereció la pena pagar por verla. Pero, llegado el final, no, no merece la pena.

En la escala MPSO le doy un 3,5.

¿Y por qué la reseño pues cuando generalmente no lo hago de películas que no me gustan? Pues porque hay una parte que, no sólo no me ha gustado, sino que me ha encantado: le meten mucha caña a las religiones. Vamos, dicen abiertamente que no hay dios, ni infierno ni nada por el estilo. Y en uno de los diálogos (aquí un pequeño spoiler hasta el siguiente párrafo, así que saltaos esto si no queréis que os destripe una escena ;) ) donde una creyente dice que no hay más mundos, sale Paul diciendo “¿Y cómo me explicas a mí?”. Sin duda lo mejor de la película, por no decir lo único. Bueno, eso y que uno de los protagonistas sabe hablar en klingon. Y, de hecho, habla. ¿Veis lo de friki del principio?

En general, si tienes una hora y media donde no tienes nada más interesante que hacer (y es difícil) y te apetece tener un ratito de sopor, te la recomiendo. En el resto de los casos, mejor busca otra opción.

Tipografía ‘Ubuntu Monospace’

¿Os acordáis de la tipografía Inconsolata que había puesto por aquí como buena fuente de ancho fijo para los editores de desarrollo? Pues he descubierto otra que, si no es tan buena, le está muy cerca. Aunque, bueno, quizás sea más por gustos que por “más buena” o “menos buena”.

Esta es la tipografía ‘Ubuntu Monospace‘, de la familia de tipografías de Ubuntu (que se pueden descargar gratuitamente y que valen para cualquier sistema operativo que soporte fuentes TrueType). Y aquí tenemos dos muestras:

Muestra de la tipografía Ubuntu Monospace en el terminal de Gnome Muestra de la tipografía Ubuntu Monospace en Eclipse

Y estas muestras se pueden comparar con la del terminal con Inconsolata y con la de Eclipse con Inconsolata.

Y a vosotros ¿cuál os gusta más? ¿Cuál usáis para desarrollar?

Formación

Es mejor educar a las personas y arriesgarse a que se vayan, a no hacer nada y arriesgarse a que se queden.

Anónimo.

Vía Mundo Geek.