Autor |
Mensaje |
Uciel
Nivel 6
Edad: 34
Registrado: 16 Ago 2010
Mensajes: 288
Carrera: Informática
|
|
Hola, tengo una duda sobre sincronizacion y uso de mutex en C/C++
Se tiene el sig codigo:
//Creamos MAX_THREAD threads que sacan por pantalla una cadena y su
//identificador
//Una vez terminan su ejecución devuelven como resultado su
//identificador
#include <pthread>
#include <stdio>
#include <stdlib>
#include <string>
#define MAX_THREADS 10
// tipo de datos y tabla con los parametros
typedef struct {
int id;
char *cadena;
} thr_param_t;
thr_param_t param[MAX_THREADS];
// tenemos que crear un array para los parámetros porque los pasamos por
// referencia. Así, si solo tuviéramos una variable para los parámetros
// al modificar esta modificaríamos todas las que habíamos pasado anteriormente
// porque los threads no se quedan con el valor sino con la dirección
// Esta es la funcion que ejecutan los threads
void* funcion_thr(void* pParametro){
thr_param_t parametro = *((thr_param_t*)pParametro);
printf("%s %d\n", parametro.cadena, parametro.id);
// Una vez terminamos, devolvemos el valor.
pthread_exit(&(parametro.id));
}
int main(){
int i, *resultadoLocalMain;
// tabla con los identificadores de los threads
pthread_t vectorDeHilos[MAX_THREADS];
// creamos los threads
printf("Creando threads...\n");
for (i=0; i<MAX_THREADS; i++) {
param[i].cadena = strdup("Hola, soy el thread numero: ");
param[i].id = i;
pthread_create(&vectorDeHilos[i], NULL, funcion_thr,( void *)¶m[i]);
}
// esperamos que terminen los threads
printf("Threads creados. Esperando que terminen...\n");
for (i=0; i<MAX_THREADS; i++) {
pthread_join(vectorDeHilos[i], (void**)&resultadoLocalMain);
printf("El thread %d devolvio el valor %d\n", i, *resultadoLocalMain);
}
// sacamos el mensajito y salimos del programa
printf("Todos los threads finalizados. Adios!\n");
return 0;
}
El asunto es que la salida, esta totalmente dessincronizada. Es decir, obtengo una salidas (pongo salidas, ya que varian cada vez que le doy "run)" de este estilo:
Creando threads...
Threads creados. Esperando que terminen...
Hola, soy el thread numero: 3
Hola, soy el thread numero: 2
Hola, soy el thread numero: 1
Hola, soy el thread numero: 0
El thread 0 devolvio el valor 0
El thread 1 devolvio el valor 1
El thread 2 devolvio el valor 2
El thread 3 devolvio el valor 0
Hola, soy el thread numero: 9
Hola, soy el thread numero: 8
Hola, soy el thread numero: 7
Hola, soy el thread numero: 6
Hola, soy el thread numero: 5
Hola, soy el thread numero: 4
El thread 4 devolvio el valor 4
El thread 5 devolvio el valor 5
El thread 6 devolvio el valor 6
El thread 7 devolvio el valor 7
El thread 8 devolvio el valor 8
El thread 9 devolvio el valor 9
Todos los threads finalizados. Adios!
Bueno, si alguien sabe donde debiera declarar los mutex (uso de "lock" y "unlock") para poder hacer que la salida sea sincronizada, se lo agradeceria eternamente =)
Saludos. Uciel
|
|
|
|
|
|
|
|
|
Uciel
Nivel 6
Edad: 34
Registrado: 16 Ago 2010
Mensajes: 288
Carrera: Informática
|
|
Bueno, quedo todo pegado el codigo y bastante feo, aca les dejo un link donde se puede visualizar de forma mas amigable:
http://ideone.com/YsfH1S
|
|
|
|
|
|
|
|
|
koreano
Nivel 9
Registrado: 15 Jul 2010
Mensajes: 1796
Carrera: No especificada
|
|
Necesitas un solo mutex (global), lo lockeas al principio de la funcion del thread y lo liberas cuando termina antes de salir
|
|
|
|
|
|
|
|
|
Uciel
Nivel 6
Edad: 34
Registrado: 16 Ago 2010
Mensajes: 288
Carrera: Informática
|
|
Ya habia probado hacer algo asi. Pero la salida sigue sin ser sincronizada. Mira aca te paso el codigo con el mutex agreagado:
http://ideone.com/miJvOQ
Una posible salida es:
Creando threads...
Threads creados. Esperando que terminen...
Hola, soy el thread numero: 6
Hola, soy el thread numero: 9
Hola, soy el thread numero: 5
Hola, soy el thread numero: 4
Hola, soy el thread numero: 3
Hola, soy el thread numero: 2
Hola, soy el thread numero: 1
Hola, soy el thread numero: 0
El thread 0 devolvio el valor 0
El thread 1 devolvio el valor 1
El thread 2 devolvio el valor 2
El thread 3 devolvio el valor 3
El thread 4 devolvio el valor 4
El thread 5 devolvio el valor 5
El thread 6 devolvio el valor 0
Hola, soy el thread numero: 8
Hola, soy el thread numero: 7
El thread 7 devolvio el valor 7
El thread 8 devolvio el valor 8
El thread 9 devolvio el valor 9
Todos los threads finalizados. Adios!
Que como puede observarse, no esta sincronizada =S
|
|
|
|
|
|
|
|
|
csebas
Nivel 9
Edad: 71
Registrado: 16 Feb 2009
Mensajes: 1634
Carrera: No especificada
|
|
No entiendo por que no lo pones en el foro de taller, el Mutex nunca te va a asegurar quien llega a la instruccion 1ro, es mas ni siquiera sirve para eso. Sirve para considerar un conjunto de instrucciones como una instruccion atomica.
La idea del Mutex es que si no lo pones, te puede llegar a salir:
El thread El thread devolvio elv alor El thread 1....y asi todo mezclado.
Con el Mutex vos logras que la impresion salga completa, antes de que otro hilo tome la salida estandar. (en este caso)
|
|
|
|
_________________ ━━━━━┓ \\
┓┓┓┓┓┃
┓┓┓┓┓┃ ヽ○ノ
┓┓┓┓┓┃ /
┓┓┓┓┓┃ ノ)
┓┓┓┓┓┃
┓┓┓┓┓┃
▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
|
|
|
Hache
Nivel 8
Registrado: 13 May 2010
Mensajes: 574
Carrera: Informática
|
|
Si la idea es solo que la impresión salga completa se puede hacer sin mutex.
Si la idea es que cada thread se ejecute estrictamente por orden de creación no necesitas threads, necesitas un loop. La idea del thread es ejecución independiente.
|
|
|
|
_________________
|
|
|
|
|
csebas
Nivel 9
Edad: 71
Registrado: 16 Feb 2009
Mensajes: 1634
Carrera: No especificada
|
|
Hache escribió:
|
Si la idea es solo que la impresión salga completa se puede hacer sin mutex.
|
Te puedo asegurar que no, ya que lo probe.
Si en C++ pones "std::cout << "valor = " << i << std::endl" , por ejemplo, son varias instrucciones, sin un Mutex el Sistema Operativo elige en que momento le da el control a un hilo, se lo saca y se lo da a otro.
Con lo cual si no haces:
mutex.lock();
std::cout << "valor = " << i << std::endl
mutex.unlock();
Sale cualquier banana.
|
|
|
|
_________________ ━━━━━┓ \\
┓┓┓┓┓┃
┓┓┓┓┓┃ ヽ○ノ
┓┓┓┓┓┃ /
┓┓┓┓┓┃ ノ)
┓┓┓┓┓┃
┓┓┓┓┓┃
▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
|
|
|
Hache
Nivel 8
Registrado: 13 May 2010
Mensajes: 574
Carrera: Informática
|
|
No hace falta mutex. He dicho.
Código:
|
char* mensaje[200];
sprintf(buffer, "Valor= %d\n", i);
write(fileno(stdout), buffer, strlen(buffer));
|
|
|
|
|
_________________
|
|
|
|
|
csebas
Nivel 9
Edad: 71
Registrado: 16 Feb 2009
Mensajes: 1634
Carrera: No especificada
|
|
Eso no compila, buffer no esta declarado :p.
Concluyendo...Depende de como lo programes hace falta o no, en tu ejemplo mensaje pasa a ser variable estatica y hola mutex jeje.
|
|
|
|
_________________ ━━━━━┓ \\
┓┓┓┓┓┃
┓┓┓┓┓┃ ヽ○ノ
┓┓┓┓┓┃ /
┓┓┓┓┓┃ ノ)
┓┓┓┓┓┃
┓┓┓┓┓┃
▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
|
|
|
Hache
Nivel 8
Registrado: 13 May 2010
Mensajes: 574
Carrera: Informática
|
|
csebas escribió:
|
en tu ejemplo mensaje pasa a ser variable estatica y hola mutex jeje.
|
No sé de donde sacaste esa idea. No tenes el contexto para aseverarlo. Es una variable local del thread.
|
|
|
|
_________________
|
|
|
|
|
csebas
Nivel 9
Edad: 71
Registrado: 16 Feb 2009
Mensajes: 1634
Carrera: No especificada
|
|
Por eso te estoy diciendo que depende del contexto, tendras o no, que usar un mutex.
|
|
|
|
_________________ ━━━━━┓ \\
┓┓┓┓┓┃
┓┓┓┓┓┃ ヽ○ノ
┓┓┓┓┓┃ /
┓┓┓┓┓┃ ノ)
┓┓┓┓┓┃
┓┓┓┓┓┃
▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
|
|
|
Hache
Nivel 8
Registrado: 13 May 2010
Mensajes: 574
Carrera: Informática
|
|
No porque es una variable local del thread.
EDIT: Esta bien. Si bien lo que digo desde el primer post es cierto (y no se requieren mutex), la verdad es que me meti al thread porque estaba aburrido. No molesto mas
|
|
|
|
_________________
|
|
|
|
|
Uciel
Nivel 6
Edad: 34
Registrado: 16 Ago 2010
Mensajes: 288
Carrera: Informática
|
|
Bueno, me parece que la mano viene mas que nada por el mal uso que le estoy queriendo dar. En definitiva, si lo que quisera es que se muestren ordenados, entonces no tendria sentido usar un Mutex creo. Para ello, directamente se hace un procesamiento secuencial y chau.
Aunqueee.... csebas dice:
"La idea del Mutex es que si no lo pones, te puede llegar a salir:
El thread El thread devolvio elv alor El thread 1....y asi todo mezclado. "
y eso no es del todo cierto. Basta ver las dos salidas que se obtienen.
Sin mutex: http://ideone.com/YsfH1S
Creando threads...
Threads creados. Esperando que terminen...
Hola, soy el thread numero: 3
Hola, soy el thread numero: 2
Hola, soy el thread numero: 1
Hola, soy el thread numero: 0
El thread 0 devolvio el valor 0
El thread 1 devolvio el valor 1
El thread 2 devolvio el valor 2
El thread 3 devolvio el valor 0
Hola, soy el thread numero: 9
Hola, soy el thread numero: 8
Hola, soy el thread numero: 7
Hola, soy el thread numero: 6
Hola, soy el thread numero: 5
Hola, soy el thread numero: 4
El thread 4 devolvio el valor 4
El thread 5 devolvio el valor 5
El thread 6 devolvio el valor 6
El thread 7 devolvio el valor 7
El thread 8 devolvio el valor 8
El thread 9 devolvio el valor 9
Todos los threads finalizados. Adios!
Con Mutex: http://ideone.com/miJvOQ
Creando threads...
Threads creados. Esperando que terminen...
Hola, soy el thread numero: 6
Hola, soy el thread numero: 9
Hola, soy el thread numero: 5
Hola, soy el thread numero: 4
Hola, soy el thread numero: 3
Hola, soy el thread numero: 2
Hola, soy el thread numero: 1
Hola, soy el thread numero: 0
El thread 0 devolvio el valor 0
El thread 1 devolvio el valor 1
El thread 2 devolvio el valor 2
El thread 3 devolvio el valor 3
El thread 4 devolvio el valor 4
El thread 5 devolvio el valor 5
El thread 6 devolvio el valor 0
Hola, soy el thread numero: 8
Hola, soy el thread numero: 7
El thread 7 devolvio el valor 7
El thread 8 devolvio el valor 8
El thread 9 devolvio el valor 9
Todos los threads finalizados. Adios!
¿como se explica eso? =S
|
|
|
|
|
|
|
|
|
Uciel
Nivel 6
Edad: 34
Registrado: 16 Ago 2010
Mensajes: 288
Carrera: Informática
|
|
EDIT de la linea en que digo:
"En definitiva, si lo que quisera es que se muestren ordenados, entonces no tendria sentido usar un Mutex creo."
Donde escribi Mutex, quise decir: Threads
|
|
|
|
|
|
|
|
|
Pablisho
Nivel 5
Registrado: 25 Sep 2008
Mensajes: 142
Carrera: Electrónica y Informática
|
|
En vez de poner un solo printf por thread hacete un bucle de printf, vas a ver como se empiezan a mezclar las cosas..
|
|
|
|
|
|
|
|
|
|
Ir a página 1, 2 Siguiente
|
Ver tema siguiente
Ver tema anterior
Podés publicar nuevos temas en este foro No podés responder a temas en este foro No podés editar tus mensajes en este foro No podés borrar tus mensajes en este foro No podés votar en encuestas en este foro No Podéspostear archivos en este foro No Podés bajar archivos de este foro
|
Todas las horas son ART, ARST (GMT - 3, GMT - 2 Horas)
Protected by CBACK CrackerTracker365 Attacks blocked.
|