He estado programando durante un tiempo en Python, pero esta es mi primera vez en multiprocesamiento.
Hice un programa que busca la temperatura ambiente de una estación meteorológica local usando beautifulsoup4 cada minuto. El programa también lee las temperaturas de varios sensores y carga todo en una base de datos Mysql. Todo esto funciona bien, pero en ocasiones (una vez al día) la obtención de datos de la estación meteorológica local falla al recuperar la página web. Esto hace que beautifulsoup inicie un bucle infinito que detiene efectivamente todas las funciones del programa. Para combatir esto, traté de probar suerte con el multiprocesamiento.
He codificado un cheque que mata el hilo adicional si aún se está ejecutando después de 10 segundos. Aquí es donde las cosas salen mal, normalmente el hermoso hilo de sopa se cierra después de 2-4 segundos cuando termina. Sin embargo, en el caso de que beautifulsoup se atasque en su bucle, no solo se termina el hilo, sino que todo el programa deja de hacer cosas por completo.
He copiado los fragmentos de código relevantes. Tenga en cuenta que algunas vars se declaran fuera de los fragmentos, el código funciona con la excepción del problema descrito anteriormente. Por cierto, soy muy consciente de que hay una gran cantidad de formas de hacer que mi código sea más eficiente. Refinar el código es algo que haré cuando funcione de manera estable :) ¡Gracias de antemano por su ayuda!
Importaciones:
...
from multiprocessing import Process, Queue
import multiprocessing
from bs4 import BeautifulSoup #sudo apt-get install python3-bs4
Sección de Beutifulsoup:
def get_ZWS_temp_out(temp):
try:
if 1==1:
response = requests.get(url)
responsestr = str(response)
if "200" in responsestr:
soup = BeautifulSoup(response.content, 'html.parser')
tb = soup.findAll("div", {"class": "elementor-element elementor-element-8245410 elementor-widget__width-inherit elementor-widget elementor-widget-wp-widget-live_weather_station_widget_outdoor"})
tb2 = tb[0].findAll("div", {"class": "lws-widget-big-value"})
string = str(tb2[0])[-10:][:4]
stringt = string[:1]
if stringt.isdigit() == True:
#print("getal ok")
string = string
elif stringt == '-':
#print("minteken")
string = string
elif stringt == '>':
#print("temp < 10")
string = string[-3:]
temp = float(string)
except Exception as error:
print(error)
Q.put(temp)
return(temp)
Programa principal:
Q = Queue()
while 1 == 1:
strings = time.strftime("%Y,%m,%d,%H,%M,%S")
t = strings.split(',')
time_numbers = [ int(x) for x in t ]
if last_min != time_numbers[4]:
targettemp = get_temp_target(targettemp)
p = Process(target=get_ZWS_temp_out, name="get_ZWS_temp_out", args=(ZWS_temp_out,))
p.start()
i = 0
join = True
while i < 10:
i = i + 1
time.sleep(1)
if p.is_alive() and i == 10: #checks to quit early otherwise another iteration
print(datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S"),": ZWS getter is running for too long... let's kill it...")
# Terminate ZWS query
p.terminate()
i = 10
join = False
if join == True:
p.join()
Gracias de antemano por tu tiempo :)
Tengo que detener manualmente el programa que da el siguiente resultado:
pi@Jacuzzi-pi:~ $ python3 /home/pi/Jacuzzi/thermometer.py
temperature sensors observer and saving program, updates every 3,5 seconds
2019-10-28 03:50:11 : ZWS getter is running for too long... let's kill it...
^CTraceback (most recent call last):
File "/home/pi/Jacuzzi/thermometer.py", line 283, in <module>
ZWS_temp_out = Q.get()
File "/usr/lib/python3.5/multiprocessing/queues.py", line 94, in get
res = self._recv_bytes()
File "/usr/lib/python3.5/multiprocessing/connection.py", line 216, in recv_bytes
buf = self._recv_bytes(maxlength)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 407, in _recv_bytes
buf = self._recv(4)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 379, in _recv
chunk = read(handle, remaining)
KeyboardInterrupt
Creo que su programa está esperando infinitamente para extraer elementos de la cola que ha creado. No puedo ver la línea en el código que ha publicado, pero aparece en el mensaje de error:
ZWS_temp_out = Q.get()
Dado que el get_ZWS_temp_out
proceso es el que agrega elementos a la cola, debe asegurarse de que el proceso se esté ejecutando antes de llamar Q.get()
. Sospecho que esta línea de código se ejecuta entre el acto de terminar el proceso agotado y reiniciar un nuevo proceso, donde en su lugar debería ser llamado después de que se crea el nuevo proceso.
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras