Я некоторое время программировал на python, но это мой первый опыт в многопроцессорности.
Я создал программу, которая очищает местную метеостанцию от температуры окружающей среды, используя beautifulsoup4 каждую минуту. Программа также считывает температуру с нескольких датчиков и загружает все в базу данных Mysql. Это все работает нормально, но иногда (один раз в день) получение данных с местной метеостанции не приводит к получению веб-страницы. Это приводит к тому, что Beautifulsoup запускает бесконечный цикл, который эффективно останавливает все функции программы. Чтобы бороться с этим, я попытался попробовать себя в многопроцессорной обработке.
Я закодировал проверку, которая убивает дополнительный поток, если он все еще работает через 10 секунд. Здесь все идет не так, как правило, поток BeautifulSoup закрывается через 2-4 секунды после завершения. Однако в случае, когда BeautifulSoup застревает в своем цикле, не только поток прерывается, но и вся программа перестает делать вещи вообще.
Я скопировал соответствующие фрагменты кода. Обратите внимание, что некоторые переменные объявлены вне фрагментов кода, код работает за исключением описанной выше проблемы. Кстати, я очень хорошо знаю, что существует множество способов сделать мой код более эффективным. Уточнение кода - это то, что я сделаю, когда он будет работать стабильно :) Заранее благодарен за помощь!
Импорт:
...
from multiprocessing import Process, Queue
import multiprocessing
from bs4 import BeautifulSoup #sudo apt-get install python3-bs4
Раздел 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)
Основная программа:
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()
Заранее спасибо за ваше время:)
Я должен вручную остановить программу, которая дает следующий вывод:
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