Re: Investigando hilos
Volver al foro (Usando Guadalinex V4)-
en mi afán de entender cada vez mejor cómo funciona Guadalinex, me pongo a hacer pruebecillas con hilos en C como el Guadiana (de vez en cuando cuando tengo tiempo ;)).
Por ahora todo ha ido bien (con algún problemilla que he ido solucionando con vuestra ayuda), pero me ha surgido una duda.
Ahora estoy con un programa donde tengo 2 funciones. En dicho programa he creado dos grupos de hilos, tal que cada grupo ejecuta "a la vez" cada una de las funciones.
Se supone que con los hilos ganas rapidez de ejecución y demás, pero me ha surgido un problema:
Si cada hilo está identificado con un DNI local de la función que ejecuta, ¿cómo puede un hilo (que ejecuta una de las funciones) pasarle su DNI a otro hilo (que ejecuta la otra función) en tiempo de ejecución, sin que ningún otro hilo -salvo el que manda el dato y el que lo recibe- pueda ver ese dato, para que no puedan modificar dicho dato durante el traspaso?
Este caso es especial porque no puedo usar alguna socorrida variable global, ya que el resto de hilos podrían ver y modificar el valor de dicha variable. Más bien supongo que debería ser algo estilo "paso por referencia" o algo así, pero no tengo ni idea de si existe algo que me solucione el problema.
El caso es que desearía que todos las "entidades" que ejecutan el código fueran hilos (no procesos).
Muchas gracias por vuestra ayuda.
...............-
NO sé si he entendido bien lo que planteas. Si lo que necesitas es proteger una variable para que ambos hilos no puedan leer o modificar al mismo tiempo dicha variable, tienes varias soluciones o mutex (ver pthread_mutex_lock y pthread_mutex_unlock) o semáforos (ver sem_open, sem_wait y sem_post).
De todas formas, si los 2 hilos se están ejecutando siempre, sólo se entrará una vez a este procedimiento y en el tendrás un bucle infinito donde realizas la acción correspondiente a ésa hebra. Por tanto, como sólo se entrará una vez, no puedes usar el parámetro del tipo (void *) que lleva el procedimiento de la hebra.
Pienso que deberías usar una variable global, pero protegerla cada vez que accedes a ella para que no pueda ser accedida por otra hebra.
Por facilidad de comprensión te recomendaría que usaras mutexes, pero para el caso será mejor semáforos.
Para ello sigue los siguientes pasos:
0) Añade la biblioteca semaphore.h
#include <semaphore.h>
1) Crea una variable global del tipo sem_t *semaforo.
2) En la hebra principal (main), abre y cierra el semáforo:
semaforo = sem_open(FICHERO_SEMAFORO, O_CREAT|O_EXCL, S_IRWXU, 1);
sem_close(semaforo);
3) En el código de cada hebra, abre el semáforo, apaga el semáforo, accedes al dato compartido, enciende el semáforo y ciérralo:
semaforo = sem_open(FICHERO_SEMAFORO, 0);
sem_wait(semaforo);
//ACCESO A LA VARIABLE COMPARTIDA
sem_post(semaforo);
sem_close(semaforo);
en mi afán de entender cada vez mejor cómo funciona Guadalinex, me pongo a hacer pruebecillas con hilos en C como el Guadiana (de vez en cuando cuando tengo tiempo ;)).
Por ahora todo ha ido bien (con algún problemilla que he ido solucionando con vuestra ayuda), pero me ha surgido una duda.
Ahora estoy con un programa donde tengo 2 funciones. En dicho programa he creado dos grupos de hilos, tal que cada grupo ejecuta "a la vez" cada una de las funciones.
Se supone que con los hilos ganas rapidez de ejecución y demás, pero me ha surgido un problema:
Si cada hilo está identificado con un DNI local de la función que ejecuta, ¿cómo puede un hilo (que ejecuta una de las funciones) pasarle su DNI a otro hilo (que ejecuta la otra función) en tiempo de ejecución, sin que ningún otro hilo -salvo el que manda el dato y el que lo recibe- pueda ver ese dato, para que no puedan modificar dicho dato durante el traspaso?
Este caso es especial porque no puedo usar alguna socorrida variable global, ya que el resto de hilos podrían ver y modificar el valor de dicha variable. Más bien supongo que debería ser algo estilo "paso por referencia" o algo así, pero no tengo ni idea de si existe algo que me solucione el problema.
El caso es que desearía que todos las "entidades" que ejecutan el código fueran hilos (no procesos).
Muchas gracias por vuestra ayuda.
Es preferible una sensación segura de inseguridad, a una falsa sensación de seguridad.......... -
-> AQUÍ <- tienes una alternativa usando mutexs.
en mi afán de entender cada vez mejor cómo funciona Guadalinex, me pongo a hacer pruebecillas con hilos en C como el Guadiana (de vez en cuando cuando tengo tiempo ;)).
Por ahora todo ha ido bien (con algún problemilla que he ido solucionando con vuestra ayuda), pero me ha surgido una duda.
Ahora estoy con un programa donde tengo 2 funciones. En dicho programa he creado dos grupos de hilos, tal que cada grupo ejecuta "a la vez" cada una de las funciones.
Se supone que con los hilos ganas rapidez de ejecución y demás, pero me ha surgido un problema:
Si cada hilo está identificado con un DNI local de la función que ejecuta, ¿cómo puede un hilo (que ejecuta una de las funciones) pasarle su DNI a otro hilo (que ejecuta la otra función) en tiempo de ejecución, sin que ningún otro hilo -salvo el que manda el dato y el que lo recibe- pueda ver ese dato, para que no puedan modificar dicho dato durante el traspaso?
Este caso es especial porque no puedo usar alguna socorrida variable global, ya que el resto de hilos podrían ver y modificar el valor de dicha variable. Más bien supongo que debería ser algo estilo "paso por referencia" o algo así, pero no tengo ni idea de si existe algo que me solucione el problema.
El caso es que desearía que todos las "entidades" que ejecutan el código fueran hilos (no procesos).
Muchas gracias por vuestra ayuda.
Es preferible una sensación segura de inseguridad, a una falsa sensación de seguridad..........-
Wenas RubenSI,
intentaré explicarme mejor:
tengo 2 funciones: func_1() y func_2(). Creo N1 'hilos1' que ejecutan func_1() y N2 'hilos2' que ejecutan func_2().
Al crear los hilos2, paso como argumento a la func_2() su DNI.
Ahora sólo estoy usando semáforos en todo el programa. Uso 1 semáforo binario 'mutex', para proteger todas las secciones críticas de ambas funciones. (No sé la diferencia entre usar un semáforo binario como mutex o usar pthread_mutex_lock y compañía).
En un momento determinado necesito pasar el DNI de UNO de los hilos2 a UNO SÓLO de los hilos1. Por tanto me gustaría saber si es posible hacer este paso de variable en tiempo de ejecución. ¿Cómo se puede enterar el hilo1 del DNI del hilo2 sin que se entere ningún otro hilo1?
Saludos
P.D: Si tienes cualquier duda coméntamela e intentaré explicarme lo mejor que pueda ;)
-> AQUÍ <- tienes una alternativa usando mutexs.
en mi afán de entender cada vez mejor cómo funciona Guadalinex, me pongo a hacer pruebecillas con hilos en C como el Guadiana (de vez en cuando cuando tengo tiempo ;)).
Por ahora todo ha ido bien (con algún problemilla que he ido solucionando con vuestra ayuda), pero me ha surgido una duda.
Ahora estoy con un programa donde tengo 2 funciones. En dicho programa he creado dos grupos de hilos, tal que cada grupo ejecuta "a la vez" cada una de las funciones.
Se supone que con los hilos ganas rapidez de ejecución y demás, pero me ha surgido un problema:
Si cada hilo está identificado con un DNI local de la función que ejecuta, ¿cómo puede un hilo (que ejecuta una de las funciones) pasarle su DNI a otro hilo (que ejecuta la otra función) en tiempo de ejecución, sin que ningún otro hilo -salvo el que manda el dato y el que lo recibe- pueda ver ese dato, para que no puedan modificar dicho dato durante el traspaso?
Este caso es especial porque no puedo usar alguna socorrida variable global, ya que el resto de hilos podrían ver y modificar el valor de dicha variable. Más bien supongo que debería ser algo estilo "paso por referencia" o algo así, pero no tengo ni idea de si existe algo que me solucione el problema.
El caso es que desearía que todos las "entidades" que ejecutan el código fueran hilos (no procesos).
Muchas gracias por vuestra ayuda.
...............-
Hasta aquí el contenido de DNI, sólo es visible por este hiloWenas RubenSI,
intentaré explicarme mejor:
tengo 2 funciones: func_1() y func_2(). Creo N1 'hilos1' que ejecutan func_1() y N2 'hilos2' que ejecutan func_2().
Al crear los hilos2, paso como argumento a la func_2() su DNI.
No termino de enterme :-DEn un momento determinado necesito pasar el DNI de UNO de los hilos2 a UNO SÓLO de los hilos1. Por tanto me gustaría saber si es posible hacer este paso de variable en tiempo de ejecución. ¿Cómo se puede enterar el hilo1 del DNI del hilo2 sin que se entere ningún otro hilo1
Si tu creas las hebras, tú tienes control sobre lo que hacen, así podrás controlar quién lee la variable y quién no.
Las hebras, por definición, comparten la zona de datos del proceso, por tanto sólo pueden acceder a su zona de datos (variables locales en func_X()) y a la del proceso contenedor de las hebras (variables globales).
Pienso que deberías por tanto como bien indicas, hacer uso de variables globales.
Existe también la opción de usar "memoria compartida" y "colas de mensajes", pero por lo que he usado, más bien van enfocadas hacia el acceso a un dato (variable o estructura) compartida por varios procesos, ya que, en el caso de procesos, al hacer un fork(), las variables globales son locales al proceso y no pueden ser vistas por otros procesos.
En definitiva, que seguimos igual. A ver si poco a poco vamos perfilando una saolución.
Es preferible una sensación segura de inseguridad, a una falsa sensación de seguridad..........-
De acuerdo, sigo aclarando ;) :
Wenas RubenSI,
intentaré explicarme mejor:
tengo 2 funciones: func_1() y func_2(). Creo N1 'hilos1' que ejecutan func_1() y N2 'hilos2' que ejecutan func_2().
Al crear los hilos2, paso como argumento a la func_2() su DNI.
Hasta aquí el contenido de DNI, sólo es visible por este hilo
Cierto, hasta aquí cada DNI es una variable local de cada hilo (con lo que ningún otro hilo del programa puede verlo).
En un momento determinado necesito pasar el DNI de UNO de los hilos2 a UNO SÓLO de los hilos1. Por tanto me gustaría saber si es posible hacer este paso de variable en tiempo de ejecución. ¿Cómo se puede enterar el hilo1 del DNI del hilo2 sin que se entere ningún otro hilo1
No termino de entenderme :-D
Si tu creas las hebras, tú tienes control sobre lo que hacen, así podrás controlar quién lee la variable y quién no.
Las hebras, por definición, comparten la zona de datos del proceso, por tanto sólo pueden acceder a su zona de datos (variables locales en func_X()) y a la del proceso contenedor de las hebras (variables globales).
Pienso que deberías por tanto como bien indicas, hacer uso de variables globales.Sí, tienes razón en lo que dices, lo que ocurre es que si hago que ese DNI sea una variable global, lo verán tanto los hilos entre los que se intercambian dicho dato como el resto de hilos. Por tanto, estos últimos hilos podrían modificarlo durante el traspaso, que es lo que no quiero que se produzca, y es lo que me está pasando, aún usando un semáforo mutex en el momento del traspaso.
Como comentario, este semáforo mutex lo uso en ambas funciones para proteger todas las secciones críticas.
Existe también la opción de usar "memoria compartida" y "colas de mensajes", pero por lo que he usado, más bien van enfocadas hacia el acceso a un dato (variable o estructura) compartida por varios procesos, ya que, en el caso de procesos, al hacer un fork(), las variables globales son locales al proceso y no pueden ser vistas por otros procesos.
En definitiva, que seguimos igual. A ver si poco a poco vamos perfilando una saolución.Pues aquí está mi aportación, jejeje
P.D:¿Sabes cuál es la diferencia entre usar funciones del estilo "sem_wait" para semáforos binarios o funciones del estilo "pthread_mutex_lock"?, porque no lo tengo nada claro.
...............-
Me parece correcto el uso que haces con los mutex. Siempre y cuando, uses un mutex común para todas las hebras. Éste debe ser declarado como global e inicializado en el main (pthread_mutex_init(&mutex, NULL);).
Sí, tienes razón en lo que dices, lo que ocurre es que si hago que ese DNI sea una variable global, lo verán tanto los hilos entre los que se intercambian dicho dato como el resto de hilos. Por tanto, estos últimos hilos podrían modificarlo durante el traspaso, que es lo que no quiero que se produzca, y es lo que me está pasando, aún usando un semáforo mutex en el momento del traspaso.
Como comentario, este semáforo mutex lo uso en ambas funciones para proteger todas las secciones críticas.
De todas formas, será mejor que pongas un pequeño trozo de código y evitaremos confusiones.
En principio tampoco lo tengo muy claro. Pero creo que el mutex que estás usando, se considera como un semáforo binario, así si haces un pthread_mutex_lock este se bloquea hasta el unlock. Luego sólo tiene 2 estados.P.D:¿Sabes cuál es la diferencia entre usar funciones del estilo "sem_wait" para semáforos binarios o funciones del estilo "pthread_mutex_lock"?, porque no lo tengo nada claro.
Por el contrario, el uso de sem_wait y sem_post, difiere en que se puede hacer varios sem_wait seguidos y hasta que no se haga el mismo numero de sem_post, el semáforo estará bloqueado. O sea, hay más de un estado.
Es preferible una sensación segura de inseguridad, a una falsa sensación de seguridad..........-
RubenSI, muchas gracias por la ayuda prestada. Al final descubrí que el problema era un error del código relacionado con los semáforos que usaba pero no directamente con lo que estábamos discutiendo.
Saludos
...............-
RubenSI, muchas gracias por la ayuda prestada. Al final descubrí que el problema era un error del código relacionado con los semáforos que usaba pero no directamente con lo que estábamos discutiendo.
De nada larq005, a ambos nos gusta aprender ;-)
Nos veremos por otro foro.Saludos
Es preferible una sensación segura de inseguridad, a una falsa sensación de seguridad..........
-
-
-
-
-
-
-
larq005
Adepto
Envíos: 204