[Python-es] Cómo gestionar dos procesos a la vez

Carlos Zuniga carlos.zun en gmail.com
Jue Ago 18 00:31:15 EDT 2016


2016-08-16 16:25 GMT-05:00 jose antonio via Python-es <python-es en python.org>:
> Saludos
> En el año 2005, jjdelcerromurciano respondió a un mensaje donde explicaba
> cómo ejecutar dos procesos a la vez.
> (https://mail.python.org/pipermail/python-es/2005-May/008573.html)
>
> No sé si seguirá en temas de python, o en el foro, aunque espero que haya
> más suscriptores que puedan ayudarme, y por eso  y me he tomado la libertad
> de escribir por si alguien tiene la amabilidad de solucionarme un problema.
>
> No he trabajado con Python nunca, pero ahora necesito una rutina para un
> proyecto que consiste en un panel informador de premios instalado sobre una
> Raspberry pi, al que se le envía información desde un Pc y se encarga de
> presentarla en una televisión por hdmi. El fondo tiene los textos y marcos
> para que se pueda escribir encima la información enviada.
>
> El problema, según mis pruebas, es que si muestro la ventana, no recibe
> información y si recibe información la muestra en la ventana, pero, si
> cambia, no puedo mostrar más.
>
> Lo he desarrollado con un servidor web y funciona correctamente, pero la
> respuesta entre el envío de la información y su presentación en pantalla es
> muy lenta.  La envío por http al servidor web de la  Raspberry y un programa
> en php genera la página web que se recarga cada segundo.
>
> Quiero que vaya más rápido y he pensado en poner una  ventana con el fondo y
> sobre ella imprimir los valores o  textos a presentar.  Necesito que pueda
> recibir mensajes por socket y presentarlos en la ventana, quedando
> disponible para repetir el proceso hasta el infinito.  He  probado a
> iplementar el código del mensaje de correo relacionado arriba,  pero no he
> conseguido que funcione.
>
> El código de la ventana, sacado de internet, es:
>
> from Tkinter import *
> ventana=Tk()
> ventana.geometry("1024x768+0+0")
> ventana.title("Ventana de pruebas")
> imgl=PhotoImage(file="z:/1.gif")
> lblIimagen=Label(ventana,image=imgl).place(x=0,y=0)
> c=Canvas(ventana,width=1024, height=768)
> c.pack()
> c.create_image(0,0, anchor=NW, image=imgl)
> t=c.create_text(600,195,fill="red", font=("Arial",82),
> text="Python")
> c.itemconfig(t, text="1.000.00")
> ventana.overrideredirect(1) # quita los márgenes
>
> ventana.mainloop()
>
>
> Y el del socket
>
> #!/usr/bin/env python
>
> #importamos el modulo socket
> import socket
>
> #instanciamos un objeto para trabajar con el socket
> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>
> #Con el metodo bind le indicamos que puerto debe escuchar y  de que servidor
> esperar conexiones
> #Es mejor dejarlo en blanco para recibir conexiones externas si es nuestro
> caso
> s.bind(("", 9999))
>
> #Aceptamos conexiones entrantes con el metodo listen, y  ademas aplicamos
> como parametro
> #El numero de conexiones entrantes que vamos a aceptar
> s.listen(1)
>
> #Instanciamos un objeto sc (socket cliente) para recibir datos, al recibir
> datos este
> #devolvera tambien un objeto que representa una tupla con los datos de
> conexion: IP y puerto
> sc, addr = s.accept()
>
>
> while True:
>
>        #Recibimos el mensaje, con el metodo recv recibimos datos y como
> parametro
>       #la cantidad de bytes para recibir
>       recibido = sc.recv(1024)
>
>       #Si el mensaje recibido es la palabra close se  cierra la aplicación
>       if recibido == "close":
>          break
>
>       #Si se reciben datos nos muestra la IP y el  mensaje recibido
>       print str(addr[0]) + " dice: ", recibido
>
>      #Devolvemos el mensaje al cliente
>      sc.send(recibido)
> print "Adios."
>
> #Cerramos la instancia del socket cliente y servidor
> sc.close()
> s.close()
>
>
>
> No necesito maravillas. Basta con que el código del servidor socket reciba
> el dato y poder escribirlo en la  ventana abierta.
>
> Con mi agradecimiento por su tiempo, tanto si me responden como si lo borra
> directamente, reciban un cordial saludo.
> José Antonio Gracia
>

Si quieres un ejemplo de algo parecido, tengo un script que utiliza Tk
y un thread que hace requests a una API web cada 5 segundos para
mostrar data (el script es de hace un par de años y la API cambió
luego así que probablemente no funcione, ojo):

https://github.com/charlieman/gw2intel/blob/master/gw2intel.py

Lo que te interesa es la clase Timer que se encarga de llamar a una
función continuamente (update_data), el Queue (data_queue) que guardar
los datos que obtiene de la API y el evento <<DataFetch>> que generas
cada vez que se obtiene data y ejecuta una función (update_content)
que actualiza la pantalla en el thread de la GUI.


Saludos


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