/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Problemas con las hebras al desconectar un cliente

 
      Índice del Foro elrincondelc.com -> Programación en Servidores
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
anacara



Registrado: 20 Mar 2007
Mensajes: 3

MensajePublicado: 20/03/2007 1:24 pm
Título: Problemas con las hebras al desconectar un cliente

Hola!

Tengo un servidor de chat en C++ que trabaja sobre Linux al cual se conectan una serie de clientes por medio de sockets.

Para atender a cada cliente se crea una hebra lectora y otra escritora y todas las hebras del servidor se comunican por medio de un fichero en el que se van escribiendo mensajes (tanto mensajes de usuario como para informar de nuevos conectados y desconectados). Dicho fichero se protege con un monitor de acceso, siguiendo un esquema lector-escritor y cada vez que un escritor anota un nuevo mensaje se envía una señal a todos las hebras que se encuentran bloqueados en una cola (uso la función pthread_cond_broadcast de pthread.h).

Durante la ejecución normal (recibir nuevas conexiones y mensajes de los clientes e informar de ellas al resto de usuarios) todo funciona bien, pero tengo problemas para desconectar clientes e informar al resto.

Cuando se recibe una solicitud de desconexión, se anota un mensaje en el fichero, se cierran los sockets y se finalizan las hebras asociadas al cliente que se ha desconectado. El problema es que sólo uno o dos de las otras hebras se despierta y accede al fichero, el resto permanecen bloquedas, por lo que los clientes no se enteran de la desconexión.

Buscando el motivo del problema he observado lo siguiente:
1. Si no cierro el socket de la hebra lectora y no la finalizo (la dejo en un bucle infinito sin hacer nada) todo funciona a la perfección.

2. Si cierro el socket y mato la hebra el resto de hebras no lee el fichero hasta que se produce una nueva conexión (que, en general, suele recuperar el socket cerrado por la hebra que murió).

Para cerrar el socket simplemente hago close(idSocket).

¿Alguien puede ayudarme?
Volver arriba
quique



Registrado: 30 Mar 2004
Mensajes: 720
Ubicación: Por ahí

MensajePublicado: 23/03/2007 4:52 am
Título:

No pongas el mismo mensaje en mas de un foro a la vez.

Leete las normas de los foros
_________________
/* no comment */
Volver arriba
ciomar



Registrado: 01 Abr 2007
Mensajes: 5

MensajePublicado: 01/04/2007 6:49 pm
Título: Re: Problemas con las hebras al desconectar un cliente

anacara escribió:
Hola!

Tengo un servidor de chat en C++ que trabaja sobre Linux al cual se conectan una serie de clientes por medio de sockets.

Para atender a cada cliente se crea una hebra lectora y otra escritora y todas las hebras del servidor se comunican por medio de un fichero en el que se van escribiendo mensajes (tanto mensajes de usuario como para informar de nuevos conectados y desconectados). Dicho fichero se protege con un monitor de acceso, siguiendo un esquema lector-escritor y cada vez que un escritor anota un nuevo mensaje se envía una señal a todos las hebras que se encuentran bloqueados en una cola (uso la función pthread_cond_broadcast de pthread.h).

Durante la ejecución normal (recibir nuevas conexiones y mensajes de los clientes e informar de ellas al resto de usuarios) todo funciona bien, pero tengo problemas para desconectar clientes e informar al resto.

Cuando se recibe una solicitud de desconexión, se anota un mensaje en el fichero, se cierran los sockets y se finalizan las hebras asociadas al cliente que se ha desconectado. El problema es que sólo uno o dos de las otras hebras se despierta y accede al fichero, el resto permanecen bloquedas, por lo que los clientes no se enteran de la desconexión.

Buscando el motivo del problema he observado lo siguiente:
1. Si no cierro el socket de la hebra lectora y no la finalizo (la dejo en un bucle infinito sin hacer nada) todo funciona a la perfección.

2. Si cierro el socket y mato la hebra el resto de hebras no lee el fichero hasta que se produce una nueva conexión (que, en general, suele recuperar el socket cerrado por la hebra que murió).

Para cerrar el socket simplemente hago close(idSocket).

¿Alguien puede ayudarme?


Si se cierra el socket, el socket no deja de existir. Dependiendo de lo que estuviera haciendo el cliente/servidor, se pone en el estado "TIME_WAIT", lo cual no libera los recursos del proceso correspondientes al file_descriptor asignado en este caso al socket (vease maquina de estado de TCP). Este motivo puede ser por el cual no se dan cuenta el resto de los threads de que se cerro el socket. Si queres ver el estado de los sockets en en sistema, utilizá la intruccion "netstat -n".
Te recomiendo que realices un esquema mas de pase de mensajes, y sincronices todo con la funcion "select()" a la hora de acceder al archivo de mensajes. Inclusive te recomendaría que utilices la misma funcion para lectura/escritura en los threads, ya que estas disparando muchos hilos por proceso. Si deseas realizar una sincronización un poco mas pareja, te recomiendo que utilices la bilbioteca de semáforos de hilos (semaphore.h), ya que los monitores no te permiten sicronizar mas de 2 hilos simultáneamente (en tu caso lectura/escritura). El motivo que se te cuelgue con el monitor, puede deberse a que los 2 hilos (escritura/lectura) generen un "deadlock" en el monitor, no permitiendo que ninguna otra hebra entre en el monitor.
Ojo con la cantidad de file descriptor habiertos, ya que cada hilo utiliza la misma tabla de filedescriptors de todo el proceso. No te sorprendas si al abrir mas de 255 sockets simultánemente, no puedas realizar mas connects o accepts. Para el archivo, te recomiendo que utilices mmap() para leer escribir el archivo, y si te quedas corto con los file descriptors, realizá algunos fork() con multihilos adentro, y hace un mapeo de memoria (mmap) con "shared memory" para que se vean las modificaciones entre los procesos...

Salu2 y suerte...
Volver arriba
      Índice del Foro elrincondelc.com -> Programación en Servidores
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com