CUESTIÓN
Esto de los hilos no funciona ni para atrás.
Con lo bien que estaba yo con el UNIX de mis
entretelas. Aquí está el código:
[...]
caracter = '-';
lpThreadHnd[0] = CreateThread(NULL, 0, imprimir, (void*)&caracter, 0,
lpThreadId);
if(lpThreadHnd[0] == NULL)
{
PERROR("CreateThread");
return 1;
}
caracter = '+';
lpThreadHnd[1] = CreateThread(NULL, 0, imprimir,
(void*)&caracter, 0,
lpThreadId + 1);
[...]
He hecho el programa, y hay algunos hilos que
simplemente no imprimen nada. ¿Qué puede
estar pasando?
SOLUCIÓN
A este error, por lo común que es, hay que prestarle atención.
Surge cuando queremos pasarle diferentes argumentos a varios hilos
y se nos ocurre la feliz idea de economizar bits y reusar la
misma variable para pasar los argumentos a los hilos. En el caso
del ejemplo, la variable caracter
se usa para pasar
un '-' al primer hilo y un '+' al segundo. Por deformación de
la programación secuencial, tendemos a pensar que cuando se
crea un hilo, se "salta" a la función del hilo
y esto no es así.
Cuando se crea un hilo nuevo, otra instancia de ejecución
comienza a existir y se ejecutará "en paralelo" con el hilo
que lo creó. Tan en paralelo como pueden ejecutarse las cosas
con una sola CPU, no obstante.
Lo que en realidad ocurre es lo siguiente:
- En la variable
caracter
almacenamos un
'-'.
- A la función del hilo le pasamos la dirección de la
variable
caracter
, pero la función del
hilo ni siquiera comienza a ejecutarse porque aún no
ha conseguido la CPU.
- Ponemos un '+' en
caracter
que sobreescribirá
el menos anterior, como es natural. Pero observad que
el primer hilo lo que tiene es un puntero, con lo que
la trampa ya se fraguó.
- Creamos el segundo hilo.
- Posteriormente, cuando el primer hilo consiga la CPU
y mire lo que hay en el puntero que le hemos pasado,
verá que hay un '+' y no el '-' que debería haber.
A la vista de todo esto, ¿no hubiera sido mejor que
CreateThread
hubiera sido diseñada para que admitiera
un valor en lugar de una referencia? Pues no.
Pasando una referencia tenemos mayor flexibilidad. Podemos pasar
cualquier objeto a la función del hilo. Incluso podemos pasar
varios parámetros. Para ello, declaramos una estructura con los
parámetros que deseamos pasar y damos un puntero a esa estructura
a CreateThread
. La función del hilo recupera los
parámetros con un sencillo casting al tipo de la estructura.
© 2003 Guillermo González Talaván.