[C con Clase] VIDA O MUERTE (concurrencia)
Programante
programante en gmail.com
Mie Feb 21 22:12:45 CET 2007
Juan Pablo Freeckman escribió:
> Bueno, al parecer tenia bastantes fallos en el codigo que expuse sobre la
> gestion de hilos. Tengo hasta el domingo antes de que me cateen para
> cambiarlo. Debo hacer una llamada a un hilo cada vez que se conecte un
> cliente. Como maximo pueden ejecutarse hasta 5 hilos a la vez. Dentro de un
> hilo se ejecuta la función ZGestionComandos() que implementa la
> funcionalidad basica del servidor y retorna 0 cuando un cliente solicita
> desconexion. Cuando se desconecta un cliente(y a continuacion se cierra el
> hilo), tendre que decrementar alguna variable para saber en todo momento el
> nº de clientes conectados. Asi por ejemplo, si tenia 5 clientes
> conectados(no debo permitir la entrada a ninguno mas), y se desconecta uno,
> entonces habran 4 conectados, y podre permitir la conexion de 1 mas. Tambien
> me interesa tener conocimiento de cuando se intenta conectar un 6º cliente
> para poder enviarle un mensaje que le informe de que el servidor esta lleno.
> El servidor es de ftp.
> Que añadiriais y cambiariais vosotros al codigo? debo basarme para
> resolverlo en el tipico problema de productor-consumidor?
>
En vez de estar creando nuevos hilos y contando cuantas conexiones
quedan, yo crearía 5 hilos al principio (o 4 si vamos a convertir en
hilo principal en uno más) y los iría usando para tratar las conexiones.
Tiene además la ventaja que es más eficiente reutilizar un hilo que
crearlos y destruirlos (tiene la desventaja de que se complica pasarle
parámetros al hilo).
Veo dos lineas de acción (aunque seguramente hay más):
-El main recibe las conexiones y se las pasa a los hilos, que esperan en
un semáforo.
-Cada hilo actúa de forma independiente, recibiendo él mismo a su cliente.
A continuación te las codifico a groso modo:
En el primer caso, acepta todas las conexiones pero sólo hay 5 activas a
la vez, las demás se van atendiendo en orden de llegada (podría
complicarse el código para que no se aceptaran más).
En el segundo, se formará una cola de hasta backlog conexiones, en una
capa inferior. El cliente no se ve conectado hasta que un hilo está
dispuesto a trabajar con él.
stack pila
int main() {
//Inicializar programa y sockets
CrearSemáforo(Inicializar a 0)
CreateThread()
CreateThread()
CreateThread()
CreateThread()
CreateThread()
while(1) {
ServiceSocket = accept(ListeningSocket, NULL, NULL);
EntrarSeccionCritica
apilar(ServiceSocket)
DejarSeccionCritica
SeñalarSemáforo
}
DWORD WorkerThread() {
while(1) {
EsperarSemaforo()
EntrarSeccionCritica
Conexion = desapilar()
DejarSeccionCritica
ZGestionComandos (Conexion)
printf("CLIENTE DESCONECTADO\n");}
}
------
Segunda opción:
SOCKET ListeningSocket
int main() {
//Inicializar programa y sockets
CreateThread()
CreateThread()
CreateThread()
CreateThread()
WorkerThread()
}
DWORD WorkerThread () {
while(1) {
EntrarSeccionCritica
ServiceSocket = accept(ListeningSocket, NULL, NULL);
SalirSeccionCritica
printf("CLIENTE CONECTADO\n");}
ZGestionComandos (ServiceSocket)
printf("CLIENTE DESCONECTADO\n");}
}
}
Más información sobre la lista de distribución Cconclase