[Python-es] ayuda con hilos de ejecución

gmail manuelcortez00 en gmail.com
Mar Dic 20 03:09:39 CET 2011


Saludos a todos, primero que nada quisiera agradecer por permitirme 
entrar a formar parte de la lista.

Quisiera ver si les será posible hecharme una mano con esto.

Lo que pasa es que estoy programando dos aplicaciones, o una aplicación 
cliente/servidor que se comunica mediante sockets.

El lío es que en el servidor he utilizado la clase threading.thread para 
hacer que el programa pueda atender múltiples clientes al mismo tiempo, 
y he ahí donde nace la complicación.

Una de las funciones del programa es que cuando reciba la palabra libre, 
ejecute una función que se encarga de contar los segundos de uno en uno, 
la función arroja como retorno a una variable el total del tiempo que ha 
transcurrido, pero con los hilos de ejecución(se encuentra dentro del 
método run de la clase) no consigo como hacer, ya que al recibir la 
palabra libre, se ejecuta el conteo, pero no puedo hacer que se detenga 
y mucho menos que muestre cual fue el total del tiempo, se detiene la 
conexión al socket, pero sigue contando el tiempo.

La función que cuenta el tiempo es esta:
     def libre(self, hora_final=0, minuto_final=0):
         #comprobamos que la variable minuto_final no tenga un valor 
igual o arriba de 60
         if minuto_final > 59:
             #si la tiene, hacemos que el nuevo valor de hora_final se 
cambie por el que salga del resultado de sumar la hora final que se 
tiene actualmente más el número que sale al dividir los minutos entre 60 
para formar una hora, su resultado es una división entera y sobrarán 
números.
             hora_final = hora_final+minuto_final/60
             #aquí hacemos que lo que sobre de la división anterior se 
asigne a los minutos, para no perder más tiempo.
             minuto_final = minuto_final%60

         #se asignan 3 variables a 0, para ir incrementándolas comforme 
avance el tiempo.
         seg = min = hora = 0
         while True:
             #cada repetición del bucle sumará 1 a la variable seg, 
dando el efecto de avanzar en los segundos.
             seg = seg+1
             #como no se puede tener más de 60 segundos, se comprueba 
que seg no valga más que 59.
             if seg > 59:
                 #cuando seg valga 60, se dividirá entre 60, lo cual 
dará un resultado de 1 y sumándolo al contador de minutos.
                 min = min+seg/60
                 #se stablece el contador de segundos de nuevo a 0 para 
reinicializar el proceso.
                 seg = 0
             #se hace lo mismo con los minutos, pero ahora añadiendo el 
valor a horas en las siguientes 3 líneas.
             if min > 59:
                 hora = hora+min/60
                 min = 0
             #se muestra el resultado al usuario.
             print "%i:%i:%i" % (hora, min, seg)
             retorno =+hora, min

             if minuto_final == 0:
                 pass
             if hora_final == 0:
                 pass
             if minuto_final > 0 and min == minuto_final:
                 print "tu tiempo terminó, gracias por tu preferencia"
                 exit()
             if hora_final > 0 and hora == hora_final and min == 
minuto_final:
                 print "tu tiempo terminó, gracias por tu preferencia"
                 exit()
             try:
                 time.sleep(1)
             except KeyboardInterrupt:
                 return retorno

Esta función espera a que se le pasen dos argumentos, horas máximas y 
minútos máximos a contar, si no se pasan argumentos, contará de forma 
infinita hasta que se le detenga.

Y aquí está la forma de implementarla en el servidor, la función de 
conteo se encuentra en una clase llamada contador:
from threading import Thread

pc = contador.contador()
#Clase con el hilo para atender a los clientes.
#En el constructor recibe el socket con el cliente y los datos del
#cliente para escribir por pantalla
class Cliente(Thread):
     def __init__(self, socket_cliente, datos_cliente):
         Thread.__init__(self)
         self.socket = socket_cliente
         self.datos = datos_cliente
     # Bucle para atender al cliente.
     def run(self):
         # Bucle indefinido hasta que el cliente envie "adios"
         activo = True
         while activo:
             # Espera por datos
             peticion = self.socket.recv(1024)
             # Contestacion a "libre"
             if peticion == "libre":
                 print str(self.datos)+ " pide tiempo libre:"
                 var = pc.libre()
                 self.socket.send("libre")
...
if __name__ == '__main__':
     # Se prepara el servidor
     server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     server.bind(("", 8000))
     server.listen(1)
     print "Esperando clientes..."

     # bucle para atender clientes
     while 1:
         # Se espera a un cliente
         socket_cliente, datos_cliente = server.accept()
         # Se escribe su informacion
         print "conectado "+str(datos_cliente)

         # Se crea la clase con el hilo y se arranca.
         hilo = Cliente(socket_cliente, datos_cliente)
         hilo.stop()


Me podríais ayudar? quisiera poder o detener el hilo de ejecución para 
sacar el valor de retorno o encontrar una manera de parar todo lo que se 
esté haciendo y saber cuanto se usó de tiempo.

saludos y gracias.



Más información sobre la lista de distribución Python-es