[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