Archivo para la categoría ‘Informática’

Optimizando sitios Web

Muy buen artículo de Ricardo Galli, el creador y mantenedor de Menéame, sobre cómo optimizar sitios Web.

Más o menos viene a decir:

  • Reducir al máximo tus CSS y Javascript; y no incluyas los que no necesites (o cárgalo más tarde).
  • Si es posible, carga los elementos bloqueantes (widgets,…) de forma paralela (hay muchas formas de hacerlo, por ejemplo usando iframes).
  • Maquetar de forma que se pueda ir “dibujando” la página antes de tener todo el HTML. Con esto se reducirá el tiempo de carga percibido por el usuario.
  • Usar dominios, no subdominios, diferentes para contenido estático.
  • Comprimir el HTML y usar sprites para las imágenes (siempre que dichos sprites no sean demasiado complejos).
  • Intercalar la generación del contenido con el envío, mandando antes las partes que primero se generan (como la cabecera) para ir “dibujando” la página en el menor tiempo posible.

De esto yo deduzco que el modelo MVC es una auténtica mierda a la hora de optimizar sitios Web: lo que hace es procesar todo y luego generar y enviar el HTML al usuario, que es justamente lo que dice Ricardo Galli que es lento y que lo que realmente reduce el tiempo de carga percibido por el usuario es dibujar la página cuanto antes, aunque todavía no se halla generado completamente.

Mira que cosas, todos poniendo al MVC como la panacea y resulta que las pruebas dicen otra cosa… ¡Ains!

La forma “fácil” de compilar el kernel de Linux en Ubuntu

Como frikis geeks de la informática que somos, si usamos cualquier sabor de GNU/Linux, puede que algún día nos entre el gusanillo de compilar nuestro propio kernel.

La forma menos fácil es bajarse los fuentes con git, configurarlo con make menuconfig, compilarlo con make y luego copiar los archivos donde corresponda. Una búsqueda en Google y nos dará todos los tutoriales que queramos.

Pero los usuarios de Debian y derivados, entre ellos Ubuntu, tenemos una forma mucho más sencilla de hacerlo:

  1. Instalamos los paquetes necesarios que incluyen el código fuente del kernel y las herramientas para compilarlo:

    $ sudo apt-get install build-essential kernel-package linux-source libncurses5-dev

  2. Descomprimir el código fuente que acabamos de instalar:

    $ cd /usr/src
    $ tar -xjf linux-source-version.tar.bz2

  3. Configurar nuestras propias opciones del kernel:

    $ cd linux-sources-version
    $ make menuconfig

  4. Crear un paquete Debian (*.deb) con el nuevo kernel (esto tardará un poco porque tiene que compilarlo). El comando make-kpkg debe ejecutarse como root, de ahí el fakeroot, aunque también se puede ejecutar con sudo con un poco de cuidado:

    $ fakeroot make-kpkg --initrd --append-to-version=nuestra-versión kernel-image kernel-headers

  5. Instalar nuestro nuevo kernel:

    $ cd ..
    $ sudo dpkg -i nombre-de-nuestro-kernel.deb

  6. Si todo ha ido bien, tendremos nuestro kernel instalado con su correspondiente entrada en el menú de GRUB. En caso de que no esté en GRUB, se debe ejecutar el comando update-grub.

Además de con los fuentes de los repositorios, también se puede hacer con los fuentes que se bajen de git teniendo en cuenta que el parámetro --append-to-version es necesario (sino puede que de el error package xxx not in control info).

Un truco: para acelerar un poco la compilación, se puede indicar a make-kpkg que lance varios procesos en paralelo. Para ello hay que exportar la variable CONCURRENCY_LEVEL con el número de procesos máximo a utilizar.

$ export CONCURRENCY_LEVEL=4

Hay que tener en cuenta que esta variable no debería ser superior al número de procesadores/núcleos del ordenador porque caería el rendimiento.

Luego, por supuesto, hay que reiniciar el sistema y elegir en la pantalla de GRUB nuestro nuevo kernel mirando que no hayamos metido la pata al configurarlo.

Y esto es todo. Si hay algún error (que lo habrá) lo ponéis en comentarios y también si os ha funcionado, si habéis obtenido mejor (o peor :P ) rendimiento, si no funcionaba…

Tipografía ‘Inconsolata’

Hace tiempo que me encontré un artículo sobre tipografías para programadores, de esas de ancho fijo que se usan en los editores. La verdad es que no me acuerdo donde lo encontré pero con una pequeña búsqueda encuentras unos cuantos.

El caso es que probando un poco desde Ubuntu (que tiene varias en los repositorios) encontré Inconsolata.

Este tipo de letra es de ancho fijo (todas los caracteres ocupan el mismo espacio) y tiene unas formas muy redondeadas aunque sin llegar a ser serif que hace que sea muy sencilla su lectura. Además, cuenta con caracteres extendidos como las vocales acentuadas, la eñe, etc.

Yo la he probado en el terminal de Gnome y en Eclipse y la verdad es que estoy encantado. Creo que de momento me quedo con ella, aunque nunca hay que dejar de lado a la omnipresente DejaVu Sans Mono.

Muestra de la tipografía Inconsolta en el terminal de Gnome Muestra de la tipografía Inconsolta en Eclipse

Día del administrador de sistemas

Sysadmin Day Cake

Como cada último viernes de julio, hoy es el día del administrador de sistemas (informáticos).

Hoy ya no lo soy a tiempo completo aunque sí que tengo una solitaria máquina a mi cargo, pero hace algo más de un año tenía cuatro sistemas para mí solito (qué bien me lo pasaba…).

Y no, nadie me ha felicitado (ni hoy ni anteriormente), pero como buen friki geek hay que comentarlo :P .

Por cierto, este día tiene su propia página.

Concatenar archivos PDF

Por curiosidad más que por otra cosa, he estado mirando cómo se crean drivers para Linux, así que, buscando en Google, me encontré con el libro «Linux Device Drivers, Third Edition». El problema es que está distribuido como 23 archivos PDF, y no me apetece andar abriendo y cerrando archivos mientras leo. Y menos si lo convierto al formato ePub para mi nuevo Papyre.

Así que buscando un poco por Internet, me encontré con una solución que funciona (a parte de alguna que otra que lo hace a medias). Eso sí, esta solución pasa por usar Ghostscript en modo comando en un terminal en Linux:

diego@box:~/ldd3:$ gs -q -sPAPERSISE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=ldd3.pdf TITLE.pdf AUTHOR.COLO.pdf COPYRIGHT.pdf ldr3TOC.fm.pdf ch00.pdf ch01.pdf ch02.pdf ch03.pdf ch04.pdf ch05.pdf ch06.pdf ch07.pdf ch08.pdf ch09.pdf ch10.pdf ch11.pdf ch12.pdf ch13.pdf ch14.pdf ch15.pdf ch16.pdf ch17.pdf ch18.pdf ldr3IX.fm.pdf

Mediante este comando se genera el archivo ldd3.pdf que es la unión de todos los demás quedando un resultado que parece que el archivo se ha generado así (vamos, yo no he notado diferencia). Ahora sólo tengo que usar Calibre para poder leerlo en el eReader.

Ver miniaturas de archivos de Photoshop (.psd) en Windows 7

Si hace tiempo ponía que para ver las miniaturas de los archivos de Photoshop en el Explorer (que no funciona de forma nativa) se podía usar ThumbView, hoy me ha surgido el mismo problema, pero en Windows 7.

La solución pasa por unos sencillos pasos:

  1. Descargar e instalar el Microsoft VisualC++ 2008 Redistributable Package.
  2. Descargar Microsoft Expression Blend pero no instalar.
  3. Descomprimir el archivo descargado con WinRAR o 7zip (o cualquier otra utilidad).
  4. Buscar el archivo PSDCodec.dll y copiarlo a C:\Archivos de programa\PSDCodec\. Crear la carpeta en caso necesario.
  5. Los pasos de descarga del Expression Blend, descompresión y búsqueda del archivo os lo podéis ahorrar descargando el archivo directamente.
  6. Ejecutar como administrador una shell o símbolo del sistema.
  7. Ejecutar el comando regsvr32 "C:\Archivos de programa\PSDCodec\PSDCodec.dll".
  8. Listo. Ahora en el explorador saldrán las miniaturas de los archivos .psd.

Otra solución es MysticThumbs, una pequeña aplicación que no sólo muestra imágenes de Photoshop (.psd) en el explorador, sino que reconoce más de veinte formatos, entre ellos .ai, .pdf, .raw, .dng… Eso sí, hay que pagar 15 dólares.

Librería jsoncpp para trabajar con JSON en C++

Cuanto te creas una aplicación, uno de sus problemas es el de la configuración. Hay que guardarla, cargarla y aplicarla. Una opción para guardarla es usar XML, un formato ampliamente conocido, estándar y con muchas librerías que te ayudarán a tratarlo. Además, hacer una DTD es muy sencillo.

El problema llega cuando la configuración es tan grande que si no tienes procesos automatizados que la carguen, ésta se vuelve inmanejable. Hay tantas líneas de código que escribir para cargar un sólo valor que es totalmente contraproducente. Y eso que existen librerías bastante buenas (yo usaba PugiXML, no es que sea la mejor pero se adaptaba perfectamente a mis necesidades).

Es por eso que he hecho algunos prototipos y he decido cambiar el formato de guardado de la configuración de mi proyecto a JSON. Y para su tratamiento he usado la librería JsonCpp.

Esta librería está escrita en C++ y tiene una interfaz similar al acceso a map‘s de C++, usando los corchetes como método de acceso, posibilitando también el acceso encadenado (como si fuesen arrays multidimensionales). También está la librería JsonGlib, pero está escrita en C y no me gusta integrar librerías en C en aplicación en C++.

Además tiene un API muy clara y sencilla que conseguirá que, tanto la inclusión en el proyecto, como la programación de la misma se vuelva muy fácil (yo apenas tardé una hora en hacer un programa que cargase, guardase y chequease un archivo JSON).

Con esto se consigue que el mantenimiento del código de cargar de la configuración se reduzca enormemente (más o menos en mi proyecto, el código se ha reducido un 15%) y sea mucho más fácil de mantener.

La única “pega” que tiene esta librería es que todavía está en la versión 0.5.0, pero habrá que estar antentos a cada mejora e incluirla en tu aplicación.

En conclusión, si necesitáis manejar archivos en formato JSON en aplicaciones escritas en C++, os recomiendo esta librería ;) .

Mi presonalizado comando less

El comando less es una utilidad de los sistemas UNIX (cualquier sistema operativo compatible con POSIX lo debería tener) que sirve para ver los contenidos de los archivos de forma completa, pudiendo navegar entre dichos contenidos y consumiendo muy pocos recursos.

El comando less puede personalizar su salida, es decir, se puede incluir información adicional del archivo que se está viendo en la visualización del mismo, como el nombre del archivo, el tamaño, en qué posición nos encontramos, etc.

Por defecto la información mostrada es escasa, por lo que una pequeña personalización nunca viene mal. A continuación os dejo la que yo tengo en mi sistema:

alias L='less -NR -P "?f%f:<stdin>.?m (%i/%m). [%s bytes] %lt/%L (%pB \%) ?x-> ?x%x"'

Más o menos muestra el número de cada línea, el nombre del archivo abierto o <stdin> en caso de que sea la entrada estándar, la página en la que estás, el tamaño, el porcentage en el que te encuentras y el siguiente archivo pasado a less (en caso de que haya).

Así, con less tienes más información de lo que estás viendo. Por supuesto esto es totalmente personalizable, así que un poco de man less no viene mal para saber como mejorarlo ;) .

Otra razón más para usar software libre

Por Internet ya hay muchas razones para usar software libre, pero aquí una más referida a la siguiente noticia:

Portaltic.es: Detenidos tres gerentes de una empresa que comercializaba software con ‘bombas lógicas’

Vamos, que una empresa vendía su software con fallos programados adrede para obligar a sus clientes a contratar el servicio de mantenimiento. ¿Y cómo es posible que sucedan estas cosas a estas alturas? Simple: por usar software privativo.

Cuando compras un software a una empresa no te queda otra que confiar en ellos, es decir, tienes que creerte que su software va a hacer lo que te dicen que hace (por lo que estás pagando) y, además, tienes que creerte que no va a hacer cosas que no quieres que haga. Pero tienes que confiar porque de ninguna manera te pueden garantizar que es cierto lo que cuentan.

Cuando vi esta noticia en televisión, también salió un directivo de Panda Software diciendo que ellos tenían a 70 personas trabajando para garantizar la calidad del software. Y hay que creele, porque no hay ninguna forma de verificar que eso sea cierto.

En cambio, con software libre, teniendo el acceso al código fuente de la aplicación por la que estás pagando, puedes contratar a quién quieras para que haga una auditoría y realmente verifique que dicho software hace lo que te han dicho que hace. Y nada más, claro.

Pero ¿de qué viven las empresas que venden software libre si estás dando el código fuente? Para esto no hay nada más que mentar a alguna empresa que ya lo hace: ¿de qué vive Red Hat? De dar servicios. La respuesta es “no vendas software, vende los servicios producidos por dicho software”. Además, como las licencias de software libre obligan a que toda modificación sea publicada, puede que otra empresa se beneficie de tu trabajo, pero estate seguro de que tú también te beneficiarás del suyo.

Venga, vale. Que una empresa privada se compre un software para gestionarse no es ningún problema. Cada empresa privada hace lo que le da la gana. El problema es cuando una empresa pública hace lo mismo: paga una millonada por un software donde no existen garantías reales de que va a funcionar como dicen.

Por esto (y por unas cuantas cosas más) es por lo que las empresas públicas deberían usar software libre y por lo que las empresas privadas deberían, cuanto menos, planteárselo.

¿Mejoras en la interfaz de Android?

Una noticia rápida: Matías Duarte se ha pasado de Palm (ahora HP) a Android. Y diréis “¿Quién coño es Matías Duarte?”. Pues es el responsable (o uno de ellos) de la interfaz gráfica de usuario del sistema operativo WebOS que traen los Palm Pre.

Sin duda es una buena noticia para los teléfonos Android, porque, como comenté hace algún tiempo, había ciertas cosas que me gustaban más en WebOS que en Android, como el hecho de poder cambiar entre aplicaciones de una forma sencilla.

Así que esperemos que con esta incorporación mejore la interfaz de Android para darle ese pequeño empujón que creo que le falta.

17 pequeñas notas sobre programación en C++

  1. C++ no es C. Usa el que más te convenga en cada momento.
  2. Si programas en C++, usa su librería estándar, STL, siempre que puedas.
  3. No reinventes la rueda, si necesitas mayor funcionalidad, usa librerías que la proporcionen y que estén en un estado de madurez suficiente, como la librería boost.
  4. No se recomienda que los castings se hagan de forma implícita o de la forma que lo hace C. Se recomienda usar su nueva sintaxis: static_cast, dynamic_cast, const_cast y reinterpret_cast.
  5. Un casting con static_cast se evalúa en tiempo de compilación y es el más parecido al casting implícito de C. Se usa para convertir un tipo de dato en otro.
  6. Un casting con dynamic_cast se usa para hacer castings en tiempo de ejecución pero sólo para objetos polimórficos, esto es, para recorrer la jerarquía de clases. No funcionará con tipos básicos.
  7. Un casting con const_cast no cambia de tipo sino que cambia los modificadores const y volatile.
  8. Un casting con reinterpret_cast se usa para hacer cambios de tipo a nivel de bits, es decir, para convertir entre tipos totalmente distintos.
  9. Una función dentro de una clase que tenga el modificador const (por ejemplo void MiClase::MiFuncion() const { ... }) no modifica el contenido del objeto (no modifica los campos del objeto). Esto se usa para ejecutar funciones dentro de instancias constantes.
  10. Una función virtual pura debe ser declarada como virtual e igualada a cero dentro de la clase: virtual void MiFuncionVirtualPura() = 0;. Este tipo de funciones deben ser implementadas en las clases derivadas. Además, no se pueden instanciar clases que tengan funciones virtuales puras.
  11. Las variables miembro (propiedades) estáticas de una clase deben ser definidas fuera de la clase para que funcionen correctamente (si no se definen así, el error lo produce el linker: Undefined reference to MiClase::count):
    class MiClase {
    	public:
    		static int count;
    }
    
    int MiClase::count = 0;
    
  12. Las clases y funciones con plantillas se deben declarar e implementar en el mismo archivo ya que, como el código se genera en tiempo de compilación, si se declara en un .h y se implementa en un .cpp, es el linker el que no encuentra el código generado. Hay más soluciones, pero ninguna es buena del todo.
  13. Usa el sistema de gestión de excepciones de C++ y evita en lo posible el uso de valores de retorno indicando errores y sentencias if ya que son mucho más propensas a errores.
  14. Las excepciones deben representar el error que se produce, no quién las lanza o desde donde se lanzan.
  15. Siempre que puedas, usa objetos creados en el stack en lugar de en el heap. Con esto evitarás fugas de memoria (memory leak en inglés) ya que los objetos se destruyen cuando finaliza el ámbito de los mismos.
  16. Usa herramientas automatizadas para probar y depurar las aplicaciones (como valgrind para fugas de memoria).
  17. Nunca confies en que lo has revisado todo.

Actualización a Ubuntu 10.04 Lucid Lynx

Imagen de inicio de Ubuntu 10.04

Hoy me he actualizado a Ubuntu 10.04 desde la versión anterior, la 9.10, mediante el actualizador automático, y me he encontrado con algún que otro problemilla:

  • Ha tardado casi cuatro horas. Esto no es un problema realmente, pero entre las descargas y la instalación con dpkg se ha tirado un buen rato. Bien es cierto que tengo unos cuantos paquetes de desarrollo como gcc, g++, apache, mysql,…
  • Después de instalar, en el reinicio, no se me veían los bordes de las ventanas, con lo que no las podía mover, ni cerrar, ni nada. Eso era porque al darle a instalar tenía activado Compiz, y en el reinicio se desactivó. Para solucionarlo, basta con ir al Menú principal > Sistema > Preferencias > Apariencia y ahí, en la solapa Efectos visuales, seleccionar cualquiera que no sea el básico (luego ya se configurará al gusto) para activar de nuevo Compiz.
  • En otro ordenador que también instalé, tuve el problema de que en el reinicio no cargó correctamente el tema Ambiance ya que yo tenía un tema personalizado. Basta con seleccionar de nuevo el tema a aplicar en Menú principal > Sistema > Preferencias > Apariencia y listo.

Por cierto que el cambio de los marrones a los morados y grises me parece muy acertado; excepto, por supuesto, el cambio de los botones de las ventanas de la derecha a la izquierda (y estuve un rato probándolos, pero no me apaño). Para cambiarlos, en la aplicación gconf-editor se va a la ruta /apps/metacity/general/button_layout y se cambia el texto close,minimize,maximize: por el texto menu:minimize,maximize,close.

A parte de esto, ningún problema. Eso sí, eso de los 10 segundos en arrancar todavía les queda un poco lejos. Cierto es que arranca rápido, más rápido que la versión anterior, pero que no se echen tantos faroles. Esperemos que la próxima versión sea la vencida.

The Ubuntu Manual

Ubuntu Manual Project

Acaba de salir The Ubuntu Manual, un proyecto que intenta crear un manual para el sistema operativo Ubuntu, una distribución de GNU/Linux.

En este manual se encuentra la información que un usuario final necesita para hacerse con el sistema, desde el principio, es decir, desde la instalación en un equipo hasta la configuración del mismo pasando por la información necesaria para el manejo de las aplicaciones que usamos en el día a día, como un navegador Web, un cliente de correo electrónico, etc. Además, por supuesto, de mantenimiento del sistema e instalación de software adicional.

Pero lo mejor, quizás, es que está en español (y en unos cuantos idiomas más), capturas de pantalla incluidas. El problema es que todavía no está en español :( .

A nivel de usuario, creo que es lo que faltaba para que la adopción de otros sistemas operativos empiece a despuntar. Bien es cierto que con Windows tampoco teníamos manual, digamos que aprendimos “de oídas”, así que ahora que tenemos oportunidad, creo que es buena idea ponerse con esto y empezar, no quizás a eliminar por completo la otra alternativa, pero sí a probar para ver, al menos, qué es lo que nos estamos perdiendo.

Si vuestro uso del ordenador es el de un usuario normal, es decir, más o menos, navegar por Internet, leer el correo electrónico, chatear, editar documentos de texto y hojas de cálculo, ver presentaciones, escuchar música y ver vídeos1, os animo a todos a probar Ubuntu, que tiene manual, o cualquier otra distribución de GNU/Linux.

1 Por supuesto se pueden hacer muchas más cosas que estas, esto sólo es el principio.

Copia de seguridad de la copia de seguridad

El disco duro que compré nuevo hace unas semanas era, principalmente, para hacer copia de seguridad de todos los datos, incluyendo la música y las películas, por eso estos días ha tocado hacer copia de seguridad de la copia de seguridad que tenía en CD para así jubilar mi antiguo disco duro de 30 GB.

El caso es que copiando los CD al disco, he visto que esa publicidad que dicen que duran hasta 10 años sin que se corrompan los datos no es del todo cierta. He pasado alrededor de 200 CD y unos 15 DVD y han fallado 13 CD no superando ninguno los 5 años; DVD no ha fallado ninguno, aunque también es cierto que son bastante más nuevos. Los CD que han fallado son de las siguientes marcas:

Marca Estropeados
Benq 5
Memorex 5
Princo Budget 2
Emtec 1

Los CD siempre han estado guardados en su caja en la habitación y sin apenas movimiento. Y en la habitación si que hay esas condiciones de lugar fresco y seco.

Con esto no quiero decir que unas marcas sean mejor que otras, pero, por ejemplo, los Princo Budget eran una tarrina de 100 a un precio irrisorio y ahí están, más de 90 siguen en perfecto estado, mientras que los Memorex, por ejemplo, que mucho prometen en su publicidad, son de los que más han fallado.

Lo bueno de esto (siempre hay un lado bueno) es que no había datos irrecuperables en ellos, sólo eran películas que, gracias a la generosidad del resto de usuarios de la red, he podido conseguir sin mayores problemas.

De esto he sacado una conclusión, y es que tanto los CD como los DVD como los Blu-ray están abocados a la desaparición. Son formatos de almacenamiento limitados, tanto en capacidad de almacenamiento de datos, como en velocidad de lectura/escritura, como en capacidades de escritura (recordemos que necesitas una grabadora). Y gracias al abaratamiento de los discos duros y a las mejoras en las tarjetas de memoria y discos SSD, creo que en poco tiempo, siempre y cuando no haya ningún lobby que los defienda, terminarán por desaparecer. Aunque hay que reconocer que tienen una ventaja, y es que no les afectan las radiaciones electromagnéticas. Pero la tecnología avanza rápido y las tarjetas de memoria van camino de soportarlo, porque sino las que viven dentro de teléfonos móviles deberían estar fritas.

Volviendo al tema de las copias, como nota curiosa, mi copia de seguridad son aproximadamente unos 400 GB, de los cuales solo unos 30 GB los he generado yo entre fotos y documentos, mientras que el resto es música y películas, aunque no cuento los correos electrónicos ni las citas de calendario, y eso ya subiría el tamaño bastante más.

Creando pthreads en Linux (y sus problemas)

Hoy toca otra vez de esos tostones informáticos que no interesan a nadie, como el de GCD, pero que lo pongo para hacer copia de seguridad de estas pequeñas investigaciones.

Estoy haciendo un proyecto donde tengo que utilizar multiproceso para que varias tareas se ejecuten simultáneamente (nunca mejor dicho) que consiste en conectar a varios equipos lanzando varios hilos para que el intento de conexión a uno no haga esperar las conexiones a los demás. Una vez lanzados todos se espera por ellos hasta que terminen de conectar para iniciar el resto del proceso.

El desarrollo es en Linux y en C++ y todo el proceso está dentro de una sola aplicación, es decir, no hay varias aplicaciones que se lanzan desde una shell de forma simultánea, no, es una única aplicación desde donde está todo el proceso, por eso no se pueden usar varios procesos sino que se usan hilos, exactamente pthreads.

Los pthreads son el estándar POSIX para hilos de ejecución. Además, también definen la sincronización de los mismos mediante mutex y variables de condición (que, por cierto, nunca he entendido su funcionamiento; yo uso semáforos).

Para facilitar la mantenibilidad del software, he implementado toda la funcionalidad mediante orientación a objetos, incluidos los hilos, semáforos, mutex, etc., por lo que para iniciar un hilo, se haría de la siguiente forma:

class MyThread : public Thread {
public:
MyThread() : Thread {}
virtual ~MyThread() {}
virtual void* run(void* arg) {
cout << “MyThread::run()” << endl;
}
};

MyThread* thread = new MyThread();

thread->start();
thread->wait();

delete thread;

Dentro de la función start() se crea un pthread y se inicia mediante la función pthread_create(...). En la función wait() se espera por el hilo hasta que finalice su ejecución mediante la función pthread_join(...).

La clase Thread cuenta también con funciones para parar un hilo, reiniciarlo, etc. También se puede pasar como parámetro la función a ejecutar o, incluso, una clase que herede de la clase ThreadFunction que tiene la función run() para que así esta implementación sea bastante polivalente.

Hasta aquí todo bien. La verdad es que funciona de forma bastante estable, creo que es sencillo de utilizar (al menos es lo que pretendo) y bastante mantenible ya que cualquier modificación afecta sólo a la clase y apenas hay que tocar el resto de código.

Pero, a partir de aquí, en cuanto se empieza a hacer un uso intensivo, es cuando comienzan los pequeños problemas.

Resulta que la función pthread_create() no sólo crea un nuevo pthread sino que también lo inicia, es decir, no hay ninguna función que sea pthread_start(), sino que para iniciar (y parar) un hilo hay que crearlo (y destruirlo). Además, los desarrolladores de los pthreads no están por la labor de hacer estas funciones.

El problema surge cuando se crean muchos hilos e inmediatamente después se espera por ellos, por ejemplo, de la siguiente forma:

#define limit 100

MyThread* threads[limit];
for(int i = 0; i < limit; i++) {
threads[i] = new MyThread();
threads[i]->start();
threads[i]->wait();
}

// no hay que olvidarse de destruirlos

El problema está en hay veces que se crea un hilo dando como resultado un pthread_t válido (el identificador del hilo), pero no da tiempo a iniciarlo antes de que se ejecute el pthread_join(), por lo tanto se está haciendo una espera sobre un hilo creado pero no iniciado. En teoría pthread_join() debería devolver un valor del tipo EINVAL o similar pero no. En la práctica lo que se produce es un fallo de segmentación, es decir, corrupción de memoria.

Para reproducir esta funcionalidad, he hecho un pequeño programa en C++ que, ejecutado varias veces, produce este comportamiento incorrecto. En este caso no he conseguido corrupción de memoria, pero tampoco es está completo.

La solución que se me ocurre es usar un semáforo que sincronice la creación y la iniciación del hilo con la espera del mismo. No es una solución demasiado elegante pero creo que funcionará.

La verdad es que el API de POSIX respecto a hilos no me parece demasiado buena, pero creo que no tengo nada que hacer. Es en estos momentos es cuando hecho de menos el API de hilos de BeOS/Haiku ;) .

Eligiendo navegador

Ventana de selección de navegador en Windows 7

Microsoft, por algún que otro problemilla entre su sistema operativo y la Unión Europea, ha tenido que dar la oportunidad de elegir el navegador Web en su flamante Windows 7. Ahora, al menos por parte de ellos, la e azul ya no estará presente en todo sistema preinstalado. Ya será cosas de los usuarios… que, lógicamente, elegirán la e azul sin ni siquiera pararse a pensar el por qué.

El caso es que todo esto quizás no hubiera ocurrido si desde el primer momento que a alguien se le ocurrió decir que Microsoft incurría en monopolio con su IE, simplemente hubieran puesto un desinstalador.

Pero claro, por aquella época no dominaban el mercado, tanto de los navegadores como casi, casi de Internet, así que quisieron imponerse a golpe de talonario. Eso sí, han firmado tantos cheques en forma de multas para la UE y en forma de salario de informático para cumplir los requisitos, que probablemente les hubiera salido mucho más barato hacer el desinstalador… y un navegador nuevo.

Y aunque hubieran hecho esto, seguro que actualmente seguirían con la hegemonía en el mercado de los navegadores (aunque no se que mercado, son gratis) porque los usuarios usamos lo que hay, no nos paramos a pensar y, ni mucho menos a instalar otra cosa.

Así que casi seguro, cuando salga esta ventanita, el ratón se moverá confuso hasta encontrar algo conocido, como es esa grande y reluciente e, donde hará clic. Y al final todo seguirá igual.