I have a long running python script for a weather station. The script captures data from the weather sensors and uploads them to a mySql database as well as weather underground.
The issue I am having is that the script will run for multiple days and then crashes without a traceback. I have been troubleshooting this for weeks to no avail. I was initially running the script in IDLE. I have also ran it in the terminal. The latest update that I "think" is the real issue is that I ran the script in Visual Studio Code and when it crashed it posted: munmap_chunk() invalid pointer in the terminal.
My understanding is that munmap_chunk is a C issue so it is most likely being generated by a module that I import. I also understand that is is thrown when a pointer is passed to free() that hasn't been obtained through malloc().
With that said, I don't know how to narrow down where the issue is actually being generated from so I can potentially correct it.
Prior to seeing the munmap_chunk error I had thought maybe it was a memory leak somewhere. I manually called the garbage collector which in almost all cases you shouldn't do. That allowed for the script to run longer before the it finally crashed again.
The main thing I'm trying to determine is how to zero in on where the issue is coming from since the script just crashes and I don't get any traceback information or exception being thrown.
#!/usr/bin/python3
from gpiozero import Button
import time
import math
import Wind_Direction
import statistics
import Database
import requests
import sys
import logging
import board
from adafruit_bme280 import basic as adafruit_bme280
logging.basicConfig(format='%(asctime)s **%(levelname)4s** - %(module)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', filename='/home/testa/testb/testc.txt', filemode = 'w', level=logging.DEBUG)
logging.debug("The program has started")
print ("\nWeather_Station_BYO: The program has started")
i2c = board.I2C() # uses board.SCL and board.SDA
# ------- WU URL and credentials ---------
WUurl = "https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?"
WUid = "TESTEST" # add your WS ID
WUpwd = "TESTEST" # add your password
WUcreds = "ID=" + WUid + "&PASSWORD="+ WUpwd
wind_count = 0 # Count how many half-rotations of the anemometer
radius_in = 3.54 # Radius of your anemometer in inches (9 cm)
wind_interval = 5 # How often (secs) to report speed
interval = 300 # 5*60 seconds = 5 minutes = 300 seconds
inches_in_mile = 63360
SECS_IN_AN_HOUR = 3600
ADJUSTMENT = 1.18 # Anemometer adjustment
BUCKET_SIZE = 0.011 # Rain gauge tips once when (.2794 mm = .011 in) of rain falls
rain_count = 0
store_speeds = []
store_directions = []
def spin():
"""Counts the number of every half-rotation of the anenmometer and returns that count"""
global wind_count
wind_count = wind_count + 1 # Every half-rotation, add 1 to count
# print("spin" + str(wind_count))
def calculate_speed(time_sec):
"""Uses the number of half-rotations stored in the global variable wind_count and the time used to count the rotations and generates a final wind speed"""
global wind_count
circumference_in = (2 * math.pi) * radius_in
rotations = wind_count / 2.0
dist_in = (circumference_in * rotations) / inches_in_mile # Calculate distance travelled by a cup in inches
mile_per_sec = dist_in / time_sec
mph = mile_per_sec * SECS_IN_AN_HOUR
final_speed = mph * ADJUSTMENT
# print("final speed" + str(final_speed))
return final_speed
def bucket_tipped():
"""Counts the number of times the rain gauge bucket filled and tipped"""
global rain_count
rain_count = rain_count + 1
# print(rain_count * BUCKET_SIZE)
def reset_rainfall():
"""Resets the global rain_count variable set in the bucket_tipped function"""
global rain_count
rain_count = 0
def reset_wind():
"""Resets the global wind_count variable set in the spin function"""
global wind_count
wind_count = 0
def read_all():
"""Reads bme280 (temp, humididty, pressure) values converts them to proper units and calculates the dewpoint"""
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
bme280.sea_level_pressure = 1013.25 # change this to match the location's pressure (hPa) at sea level
humidity = bme280.humidity # % Relative humidity
pressure = bme280.pressure * 100 / 3386 # Pascals converted to inHg
ambient_temperature = bme280.temperature * 9/5 + 32 # Convert to fahrenheit rounded
b = 17.62
c = 243.12
gamma = (b * bme280.temperature /(c + bme280.temperature)) + math.log(bme280.humidity / 100.0)
dewpoint = (c * gamma) / (b - gamma)
return humidity, pressure, ambient_temperature, dewpoint
wind_speed_sensor = Button(5)
wind_speed_sensor.when_pressed = spin # Whenever the wind sensor magnet closes the reed switch then add 1 to the number of rotations
# temp_probe = ds18b20_therm.DS18B20()
rain_sensor = Button(6)
rain_sensor.when_pressed = bucket_tipped
db = Database.weather_database()
i = 1
while db.wxlogin() != True:
time.sleep(30)
i = i + 1
if (i>5):
logging.debug("Could not establish a connection to the mysql database and program will be terminated.")
time.sleep(5)
sys.exit("Could not establish connection") # Exit the script after i amount of connection attempts
logging.debug("Initial connection to database was successful!")
print("\nWeather_Station_BYO: Initial connection to database was successful!")
# Loop to measure wind speed at 300-second intervals
while True:
try:
start_time = time.time()
while time.time() - start_time <= interval:
# print("In loop 1")
wind_start_time = time.time()
reset_wind()
while time.time() - wind_start_time <= wind_interval:
# print("In loop 2")
store_directions.append(Wind_Direction.get_value(wind_interval)) # wind_interval is how long to take measuremennts for wind direction
final_speed = calculate_speed(wind_interval) # Add this speed to the list & wind_interval is how long to take measurements for wind speed
store_speeds.append(final_speed)
logger = logging.getLogger(__name__)
logger.debug("Wind speed and direction obtained")
# print("Out of both loops")
# print("stored directions " + str(store_directions))
# print("stored speeds " + str(store_speeds))
wind_dir = Wind_Direction.get_average(store_directions)
wind_gust = max(store_speeds)
wind_speed = statistics.mean(store_speeds)
rainfall = rain_count * BUCKET_SIZE
reset_rainfall()
store_speeds = []
store_directions = []
humidity, pressure, ambient_temp, dewpoint = read_all()
logger.debug("Humidity, pressure, ambient_temp and dewpoint obtained")
# print(wind_dir)
if 348.75 <= wind_dir or wind_dir <= 11.25:
wind_direction = 'N'
elif 11.26 <= wind_dir <= 33.75:
wind_direction = 'NNE'
elif 33.76 <= wind_dir <= 56.25:
wind_direction = 'NE'
elif 56.26 <= wind_dir <= 78.75:
wind_direction = 'ENE'
elif 78.76 <= wind_dir <= 101.25:
wind_direction = 'E'
elif 101.25 <= wind_dir <= 123.75:
wind_direction = 'ESE'
elif 123.76 <= wind_dir <= 146.25:
wind_direction = 'SE'
elif 146.26 <= wind_dir <= 168.75:
wind_direction = 'SSE'
elif 168.76 <= wind_dir <= 191.25:
wind_direction = 'S'
elif 191.26 <= wind_dir <= 213.75:
wind_direction = 'SSW'
elif 213.76 <= wind_dir <= 236.25:
wind_direction = 'SW'
elif 226.26 <= wind_dir <= 258.75:
wind_direction = 'WSW'
elif 258.76 <= wind_dir <= 281.25:
wind_direction = 'W'
elif 281.26 <= wind_dir <= 303.75:
wind_direction = 'WNW'
elif 303.76 <= wind_dir <= 326.25:
wind_direction = 'NW'
elif 326.25 <= wind_dir <= 348.75:
wind_direction = 'NNW'
else: wind_direction = ''
#print('',wind_direction, 'Wind Direction \n',round(wind_speed,1), 'Wind Speed (mph) \n', round(wind_gust,1),'Wind Gust (mph) \n', round(rainfall,1), 'Rainfall (in) \n',
# round(humidity,1), '% Relative Humidity \n', round(dewpoint,1), 'Dew Point F \n', round(pressure,2), 'Barometric Pressure (inHg) \n', round(ambient_temp,1), 'Temperature F \n')
i = 1
while db.check_connection() != True:
time.sleep(30)
i = i + 1
if (i>5):
logger.debug("Connection to the mysql database was disconnected and connection could not be restablished. Program will be terminated.")
time.sleep(5)
sys.exit("Could not re-establish connection") # Exit the script after i amount of connection attempts
db.wxlogin()
db.insert(1,round(ambient_temp,1), 0, 0, round(pressure,2), round(humidity,1), round(dewpoint,1), wind_direction, round(wind_speed,1), round(wind_gust,1), round(rainfall,1)) # 10 items
# Weatherunderground
# print("Uploading to Weather Underground")
f_date = "&dateutc=now"
f_humid = "&humidity=" + str(humidity) # % Relative humidity
f_wspeed = "&windspeedmph=" + str(wind_speed) # mph
f_gust = "&windgustmph=" + str(wind_gust) # mph
f_airtemp = "&tempf=" + str(ambient_temp) # degrees F
f_rain = "&rainin=" + str(rainfall) # inches
f_press = "&baromin=" + str(pressure) # inches
# f_groundtemp = "&soiltempf=" + str(ground_temp_f) # degrees F
f_winddir = "&winddir=" + str(wind_dir) # degrees
f_action = "&action=updateraw"
try:
r = requests.get(WUurl+WUcreds+f_date+f_humid+f_wspeed+f_winddir+f_gust+f_airtemp+f_rain+f_press+f_action, timeout = 30)
print("\nReceived " + str(r.status_code) + " " + str(r.text) + " from WU")
except requests.ConnectionError as e:
logger.debug("HTTP Error - Connection Error. Make sure you are connected to the internet. Technical details given below.\n")
logger.debug(str(e))
print("\nHTTP Error - Connection Error. Make sure you are connected to internet. Technical details given below.\n")
print(str(e))
continue
except requests.Timeout as e:
logger.debug("HTTP Error - Timeout Error")
logger.debug(str(e))
print("\nHTTP Error - Timeout Error")
print(str(e))
continue
except requests.RequestException as e:
logger.debug("HTTP Error - General Error")
logger.debug(str(e))
print("\nHTTP Error - General Error")
print(str(e))
continue
except KeyboardInterrupt:
print("\nSomeone closed the program")
if (str(r.status_code) != '200'):
logger.debug("Upload to Weather Underground was not sucessful. HTTP Response Code: " + str(r.status_code) + " " + str(r.text))
except Exception:
logger.exception("Unhandled exception in the script!", exc_info = True)
Traceback from faulthandler in VSCode:
munmap_chunk(): invalid pointer
Fatal Python error: Aborted
Thread 0xb0fa5440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 539 in held
File "/usr/lib/python3.7/threading.py", line 865 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey.py", line 1054 in __call__
Thread 0xb27ff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 543 in held
File "/usr/lib/python3.7/threading.py", line 865 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey.py", line 1054 in __call__
Thread 0xb31ff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/pydevd.py", line 246 in _on_run
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py", line 46 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Thread 0xb3bff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/pydevd.py", line 200 in _on_run
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py", line 46 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Thread 0xb45ff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 296 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_timeout.py", line 43 in _on_run
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py", line 46 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Thread 0xb4fff440 (most recent call first):
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py", line 219 in _read_line
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py", line 237 in _on_run
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py", line 46 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Thread 0xb599b440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/queue.py", line 179 in get
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py", line 382 in _on_run
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py", line 46 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Current thread 0xb6f34b40 (most recent call first):
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 85 in _words_to_int
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 220 in _read
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 157 in value
File "/home/pi/Liberty Ridge WX Reduced/Wind_Direction.py", line 97 in get_value
File "/home/pi/Liberty Ridge WX Reduced/Liberty_Ridge_WX.py", line 199 in <module>
File "/usr/lib/python3.7/runpy.py", line 85 in _run_code
File "/usr/lib/python3.7/runpy.py", line 96 in _run_module_code
File "/usr/lib/python3.7/runpy.py", line 263 in run_path
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 285 in run_file
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 444 in main
File "/home/pi/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/__main__.py", line 45 in <module>
File "/usr/lib/python3.7/runpy.py", line 85 in _run_code
File "/usr/lib/python3.7/runpy.py", line 193 in _run_module_as_main
Traceback from faulthandler in terminal:
munmap_chunk(): invalid pointer
Fatal Python error: Aborted
Thread 0xb44ff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 539 in held
File "/usr/lib/python3.7/threading.py", line 865 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Thread 0xb4eff440 (most recent call first):
File "/usr/lib/python3.7/threading.py", line 300 in wait
File "/usr/lib/python3.7/threading.py", line 552 in wait
File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 539 in held
File "/usr/lib/python3.7/threading.py", line 865 in run
File "/usr/lib/python3.7/threading.py", line 917 in _bootstrap_inner
File "/usr/lib/python3.7/threading.py", line 885 in _bootstrap
Current thread 0xb6f53b40 (most recent call first):
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 85 in _words_to_int
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 220 in _read
File "/usr/lib/python3/dist-packages/gpiozero/spi_devices.py", line 157 in value
File "/home/pi/Liberty Ridge WX Reduced/Wind_Direction.py", line 97 in get_value
File "/home/pi/Liberty Ridge WX Reduced/Liberty_Ridge_WX.py", line 189 in <module>
Aborted
I'm running very similar code on my Raspberry Pi weather station, and also get the munmap_chunk() error after a couple of days, running either from a command line or from Thonny.
Like you, I get no information, apart from the munmap_chunk() line. That makes me think the error is not in Python, as that would surely provide trace information. So, maybe it's from the libraries Python uses, or from the part of the operating system that does memory management.
Here's what I believe to be the source code for where the error happens, and the comments are interesting...
static void
munmap_chunk (mchunkptr p)
{
INTERNAL_SIZE_T size = chunksize (p);
assert (chunk_is_mmapped (p));
/* Do nothing if the chunk is a faked mmapped chunk in the dumped
main arena. We never free this memory. */
if (DUMPED_MAIN_ARENA_CHUNK (p))
return;
uintptr_t block = (uintptr_t) p - prev_size (p);
size_t total_size = prev_size (p) + size;
/* Unfortunately we have to do the compilers job by hand here. Normally
we would test BLOCK and TOTAL-SIZE separately for compliance with the
page size. But gcc does not recognize the optimization possibility
(in the moment at least) so we combine the two values into one before
the bit test. */
if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0))
malloc_printerr ("munmap_chunk(): invalid pointer");
atomic_decrement (&mp_.n_mmaps);
atomic_add (&mp_.mmapped_mem, -total_size);
/* If munmap failed the process virtual memory address space is in a
bad shape. Just leave the block hanging around, the process will
terminate shortly anyway since not much can be done. */
__munmap ((char *) block, total_size);
}
In the end, I decided a better thing to do was restart the program once a day, but I didn't want to use crontab, rc.local or similar. There's actually a way for a Python program to restart itself! I found it here https://blog.petrzemek.net/2014/03/23/restarting-a-python-script-within-itself/
Here's my test program...
#!/usr/bin/env/python3
import sys
import os
import time
import datetime as dt
began = dt.datetime.now()
print("Began at ", str(began))
ending = began + dt.timedelta(minutes = 2)
print("Ending at ", str(ending))
while True:
time.sleep(10)
present = dt.datetime.now()
print(" It's ", str(present))
if present > ending:
print("Time's up!")
os.execv(sys.executable, ['python3'] + sys.argv)
quit()
I think amending your weather station code to restart itself daily, before the munmap_chunk() error happens is likely to be easier than finding out why it happens.
Update:
That's what I did, adding this code before the main loop...
ending = dt.datetime.now() + dt.timedelta(hours = 24)
...and this at the end of the main loop
present = dt.datetime.now()
if present > ending:
print("Time for my 24 hour restart!")
os.execv(sys.executable, ['python3'] + sys.argv)
quit()
The program restarts every day (approximately), and has so far run for five days without the munmap_chunk() error.
Related
So I have a major issue with my alarm function in the clock I'm making in Python, a Tkinter error regarding two split functions in my code. I printed out the split components in both cases, and all of them seemed to split properly. I do not know what the issue is.
Here is the code
def alarm():
if toggledtime == "AM/PM":
mainAMPM_time = dt.datetime.now().strftime("%H:%M %p")
alarm_timeAMPMmain = get_alarm_time_entry.get()
alarm_timeAMPM,alarm_period= alarm_timeAMPMmain.split(' ')
alarm_hourAMPM, alarm_minutesAMPM = alarm_timeAMPM.split(':')
main_timeAMPM,main_period = mainAMPM_time.split(' ')
main_hourAMPM, main_minutesAMPM = main_timeAMPM.split(':')
print(alarm_timeAMPMmain)
print()
print(alarm_hourAMPM)
print(alarm_minutesAMPM)
print(alarm_period)
print()
else:
mainMilitary_time= dt.datetime.now().strftime("%H:%M")
alarm_timeMilitarymain = get_alarm_time_entry.get()
alarm_hourMilitary, alarm_minutesMilitary = alarm_timeMilitarymain.split(':')
main_hourMilitary, main_minutesMilitary = mainMilitary_time.split(':')
print(alarm_timeMilitarymain)
print()
print(alarm_hourMilitary)
print(alarm_minutesMilitary)
print()
And here is both errors I get. They are similar Tkinter Errors.
Traceback (most recent call last):
File "/home/arnabd/miniconda3/envs/PythonEnV2/lib/python3.9/tkinter/__init__.py",
line 1892, in __call__
return self.func(*args)
File "/home/arnabd/miniconda3/envs/PythonEnV2/lib/python3.9/tkinter/__init__.py",
line 814, in callit
func(*args)
File "/home/arnabd/Documents/PythonVSCODEProjects/Clock.py", line 55, in alarm
alarm_timeAMPM,alarm_period= alarm_timeAMPMmain.split(' ')
ValueError: not enough values to unpack (expected 2, got 1)
Traceback (most recent call last):
File "/home/arnabd/miniconda3/envs/PythonEnV2/lib/python3.9/tkinter/__init__.py",
line 1892, in __call__
return self.func(*args)
File "/home/arnabd/miniconda3/envs/PythonEnV2/lib/python3.9/tkinter/__init__.py",
line 814, in callit
func(*args)
File "/home/arnabd/Documents/PythonVSCODEProjects/Clock.py", line 62, in alarm
alarm_hourMilitary, alarm_minutesMilitary = alarm_timeMilitarymain.split(':')
ValueError: not enough values to unpack (expected 2, got 1)
Here is the output from those print statements:
10:24 AM
10
24
AM
10
17
10:17
Edit: I tried other delimiters and rechecked the output of my code to ensure I am using the right one. I want to say that the alarm actually starts, but does not produce a noise that I coded in. I'll put in the code for that.
if toggledtime == "AM/PM":
if int(alarm_hourAMPM) == int(main_hour) and int(alarm_minutesAMPM) == int(main_minutesAMPM) and alarm_period == main_period:
for i in range(3):
alarm_status_label.config(text='Time Is Up')
print("\a")
get_alarm_time_entry.config(state='enabled')
set_alarm_button.config(state='enabled')
get_alarm_time_entry.delete(0,END)
alarm_status_label.config(text = '')
else:
alarm_status_label.config(text='Alarm Has Started')
get_alarm_time_entry.config(state='disabled')
set_alarm_button.config(state='disabled')
alarm_status_label.after(1000, alarm)
else:
if int(alarm_hourMilitary) == int(main_hourMilitary) and int(alarm_minutesMilitary) == int(main_minutesMilitary):
for i in range(3):
alarm_status_label.config(text='Time Is Up')
print("\a")
get_alarm_time_entry.config(state='enabled')
set_alarm_button.config(state='enabled')
get_alarm_time_entry.delete(0,END)
alarm_status_label.config(text = '')
else:
alarm_status_label.config(text='Alarm Has Started')
get_alarm_time_entry.config(state='disabled')
set_alarm_button.config(state='disabled')
alarm_status_label.after(1000, alarm)
I am attempting to perform an SQL insertion using a thread, and I am losing connection and getting an error back from SQL. I am unable to identify what is the problem on my own, and would like to ask StackOverflow what they think could be the source of the error.
I have attached the error message first then the code that is being run.
Error
Exception in thread Thread-160:
Traceback (most recent call last):
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 161, in send_plain
self.sock.sendall(packet)
File "/usr/lib/python3.6/ssl.py", line 975, in sendall
v = self.send(byte_view[count:])
File "/usr/lib/python3.6/ssl.py", line 944, in send
return self._sslobj.write(data)
File "/usr/lib/python3.6/ssl.py", line 642, in write
return self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2162)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "trt_yolo_tracklite_mysql.py", line 148, in mysql_insert
cursor.execute(sql_op, (copy_today, copy_time, confidence, identity, x1, y1, x2, y2, img_blob))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 568, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 846, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 495, in _send_cmd
packet_number, compressed_packet_number)
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 164, in send_plain
errno=2055, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at '192.168.1.131:3306', system error: 8 EOF occurred in violation of protocol (_ssl.c:2162)
and it throws similar errors for every iteration of the loop
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "trt_yolo_tracklite_mysql.py", line 148, in mysql_insert
cursor.execute(sql_op, (copy_today, copy_time, confidence, identity, x1, y1, x2, y2, img_blob))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 568, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 846, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 495, in _send_cmd
packet_number, compressed_packet_number)
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 164, in send_plain
errno=2055, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at '192.168.1.131:3306', system error: 8 EOF occurred in violation of protocol (_ssl.c:2162)
Exception in thread Thread-164:
Traceback (most recent call last):
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 161, in send_plain
self.sock.sendall(packet)
File "/usr/lib/python3.6/ssl.py", line 975, in sendall
v = self.send(byte_view[count:])
File "/usr/lib/python3.6/ssl.py", line 944, in send
return self._sslobj.write(data)
File "/usr/lib/python3.6/ssl.py", line 642, in write
return self._sslobj.write(data)
BrokenPipeError: [Errno 32] Broken pipe
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "trt_yolo_tracklite_mysql.py", line 148, in mysql_insert
cursor.execute(sql_op, (copy_today, copy_time, confidence, identity, x1, y1, x2, y2, img_blob))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 568, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 846, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/connection.py", line 495, in _send_cmd
packet_number, compressed_packet_number)
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 164, in send_plain
errno=2055, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at '192.168.1.131:3306', system error: 32 Broken pipe
Exception in thread Thread-162:
Traceback (most recent call last):
File "/home/user/.local/lib/python3.6/site-packages/mysql/connector/network.py", line 161, in send_plain
self.sock.sendall(packet)
File "/usr/lib/python3.6/ssl.py", line 975, in sendall
v = self.send(byte_view[count:])
File "/usr/lib/python3.6/ssl.py", line 944, in send
return self._sslobj.write(data)
File "/usr/lib/python3.6/ssl.py", line 642, in write
return self._sslobj.write(data)
BrokenPipeError: [Errno 32] Broken pipe
During handling of the above exception, another exception occurred:
Here is the code being run:
This script demonstrates how to do real-time object detection with
TensorRT optimized YOLO engine.
"""
import os
import time
import argparse
import cv2
import pycuda.autoinit # This is needed for initializing CUDA driver
import mysql.connector
from mysql.connector import pooling
from datetime import date
#import local classes and their functions
from utils.yolo_classes import get_cls_dict
from utils.camera import add_camera_args, Camera
from utils.display import open_window, set_display, show_fps
from utils.visualization import BBoxVisualization
from utils.yolo_with_plugins_tracklite_mysql import TrtYOLO
from tracklite.utils.parser import get_config
from threading import Thread, Lock
WINDOW_NAME = 'TrtYOLODemo'
database = mysql.connector.connect(
host='192.168.1.131',
user='*******'
password='*********',
database='bird_detections'
)
cursor = database.cursor()
sql_op = 'INSERT INTO nano_detections (DATE, TIME, CONFIDENCE, IDENTITY, X1, Y1, X2, Y2, IMG) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)'
mutex = Lock()
WINDOW_NAME = 'TrtYOLODemo'
def parse_args():
"""Parse input arguments."""
desc = ('Capture and display live camera video, while doing '
'real-time object detection with TensorRT optimized '
'YOLO model on Jetson')
parser = argparse.ArgumentParser(description=desc)
parser = add_camera_args(parser)
parser.add_argument(
'-c', '--category_num', type=int, default=80,
help='number of object categories [80]')
parser.add_argument(
'-m', '--model', type=str, required=True,
help=('[yolov3-tiny|yolov3|yolov3-spp|yolov4-tiny|yolov4|'
'yolov4-csp|yolov4x-mish]-[{dimension}], where '
'{dimension} could be either a single number (e.g. '
'288, 416, 608) or 2 numbers, WxH (e.g. 416x256)'))
parser.add_argument(
'-l', '--letter_box', action='store_true',
help='inference with letterboxed image [False]')
args = parser.parse_args()
return args
def loop_and_detect(cam, trt_yolo, conf_th, vis):
"""Continuously capture images from camera and do object detection.
# Arguments
cam: the camera instance (video source).
trt_yolo: the TRT YOLO object detector instance.
conf_th: confidence/score threshold for object detection.
vis: for visualization.
"""
today = date.today()
#full_screen is set to false by default
full_scrn = False
#fps is set at 0 by default
fps = 0.0
#create time variable for measuring the frames per second in real time
tic = time.time()
#while loop to perform inference
while True:
mutex.acquire()
today_formatted = today.strftime("%y-%m-%d")
time_formatted = time.strftime("%H:%M:%S")
#determine if window is closed or not ????
#break the loop if window is closed
if cv2.getWindowProperty(WINDOW_NAME, 0) < 0:
break
#create img object from a reading of the camera frame
img = cam.read()
image_blob = cv2.imencode('.jpg', img)[1].tostring()
#break loop if the camera frame is none
if img is None:
break
#create bounding box coordinate, detection confidence, and class id from the detect function of the trt_yolo object.
img, outputs, scores = trt_yolo.detect(img, conf_th)
t = Thread(target=mysql_insert, args=(outputs, scores, today_formatted, time_formatted, image_blob))
mutex.release()
t.start()
mutex.acquire()
#img = vis.draw_bboxes(img, boxes, confs, clss)
img = show_fps(img, fps)
cv2.imshow(WINDOW_NAME, img)
toc = time.time()
curr_fps = 1.0 / (toc - tic)
# calculate an exponentially decaying average of fps number
fps = curr_fps if fps == 0.0 else (fps*0.95 + curr_fps*0.05)
tic = toc
key = cv2.waitKey(1)
if key == 27: # ESC key: quit program
break
elif key == ord('F') or key == ord('f'): # Toggle fullscreen
full_scrn = not full_scrn
set_display(WINDOW_NAME, full_scrn)
mutex.release()
def mysql_insert(outputs, scores, today, time, img_blob):
mutex.acquire()
copy_outputs = outputs
copy_scores = scores
copy_today= today
copy_time = time
mutex.release()
if len(outputs) > 0:
bbox_xyxy = copy_outputs[:, :4]
identities = copy_outputs[:, -1]
for box, identity, score in zip(bbox_xyxy, identities, copy_scores):
if score > 0 :
x1 = str(box[0])
y1 = str(box[1])
x2 = str(box[2])
y2 = str(box[3])
identity = str(identity)
confidence = str(score)
cursor.execute(sql_op, (copy_today, copy_time, confidence, identity, x1, y1, x2, y2, img_blob))
database.commit()
#cursor.close()
#conn.close()
def test_insert():
sql_insert = 'INSERT INTO test_table(TEST_STRING) VALUES (%s)'
string_to_insert = 'TEST'
cursor.execute(sql_insert, (string_to_insert))
def main():
cfg_file = "./tracklite/configs/deep_sort.yaml"
cfg = get_config()
cfg = cfg.merge_from_file(cfg_file)
#parse arguments
args = parse_args()
#raise errors for lack of arguments, such as the category number and the model file
if args.category_num <= 0:
raise SystemExit('ERROR: bad category_num (%d)!' % args.category_num)
if not os.path.isfile('yolo/%s.trt' % args.model):
raise SystemExit('ERROR: file (yolo/%s.trt) not found!' % args.model)
#camera object instantiated with arguments
cam = Camera(args)
#raise error if cameras is not opened
if not cam.isOpened():
raise SystemExit('ERROR: failed to open camera!')
#create list of classes to be detected
cls_dict = get_cls_dict(args.category_num)
#instantiate vis object with class_dict passed as an argument
#BBOXVisualization contains code to draw boxes and assign colors to each class
vis = BBoxVisualization(cls_dict)
#instantiate the TtrYOLO object based on the arguments given in the command to start trt_yolo.py
trt_yolo = TrtYOLO(args.model, cfg, args.category_num, args.letter_box)
#open a window based on camera height and width
open_window(
WINDOW_NAME, 'Camera TensorRT YOLO Demo',
cam.img_width, cam.img_height)
#loop and perform detections
loop_and_detect(cam, trt_yolo, conf_th=0.3, vis=vis)
cam.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
#Decoding Image From SQL:
#nparr = np.fromstring(STRING_FROM_DATABASE, np.uint8)
#img = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR)
I at first thought the issue was because I needed to use pooled connections, but I am encountering the same error or an error related to exhausted connections when I modify the above code to use pooled connections. Based on the error message I think that there is a problem in the data that I am inserting, but I do not know how to properly read this error and I need some help.
I am using pyFirmata to move servo motors for my project. When ever i run my project, it runs two times and the following errors come out. The code and the result is given below.
from pyfirmata2 import Arduino, SERVO
import time
board = Arduino('COM3')
servo = board.get_pin('d:9:s')
board.digital[9].mode = SERVO
# def rotateServo(pin, angle):
# board.digital[9].write(angle)
# time.sleep(0.1)
current_angle = servo.read()
while True:
# for i in range (0,180):
# rotateServo(9, i)
print(current_angle)
if current_angle != 0 or current_angle == 0:
servo.write(0)
print("0")
time.sleep(2)
servo.read()
servo.write(90)
print("90")
time.sleep(2)
errors:
*C:\Python_Virtualenv\Scripts\python.exe "E:/Python Projects/servo.py"
0
0
90
0
Traceback (most recent call last):
File "E:\Python Projects\servo.py", line 18, in <module>
servo.write(0)
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\pyfirmata2\pyfirmata2.py", line 608, in write
self.board.sp.write(msg)
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 317, in write
raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: WriteFile failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
Exception ignored in: <function Board.__del__ at 0x000001F25EB3D040>
Traceback (most recent call last):
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\pyfirmata2\pyfirmata2.py", line 148, in __del__
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\pyfirmata2\pyfirmata2.py", line 385, in exit
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\pyfirmata2\pyfirmata2.py", line 528, in _set_mode
File "C:\Users\n1v3d\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 317, in write
serial.serialutil.SerialException: WriteFile failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
Process finished with exit code 1*
Please tell me how to fix this error!
I have a dataframe that has 15,000 host IP addresses (IP v4 and IP v6) I am trying to check which of these hosts are up(running) by pinging the hosts.
I have the following code that I have written
def ping_host(hostname):
# hostname = "10.0.0.10 #example
print(hostname)
if hostname != hostname:
return "No Hostname"
response = os.system("ping -c 1 " + hostname + " > /dev/null 2>&1")
# and then check the response...
if response == 0:
print(hostname, 'is up!')
return "Up"
else:
print(hostname, 'is down!')
return "Down"
df['Host_Status'] = df['IP Addresses'].apply(ping_host)
This takes for ever to complete. Is there a better/faster way to do this?
I did try -
df['Host_Status'] = df['IP Addresses'].swifter.apply(ping_host)
but even that didn't increase the speed by much.
Edit 1-
I let this run using multi-threading for 5 hours using 32/64/256 threads(I think only 32 threads were working at any given point) but at the end of the script
from multiprocessing.pool import ThreadPool
def ping_host(hostname):
# hostname = "10.0.0.10 #example
print(hostname)
if hostname != hostname:
return "No Hostname"
response = os.system("ping -c 1 " + hostname + " > /dev/null 2>&1")
# and then check the response...
if response == 0:
print(hostname, 'is up!')
return "Up"
else:
print(hostname, 'is down!')
return "Down"
# you can fiddle with pool size
with ThreadPool(processes=32) as t:
df['Host_Status'] = t.map(ping_host, df['IP Addresses'])
df.to_excel('output.xlsx')
there when I tried to export it I got the following error -
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_comm/pydev_transport.py", line 64, in _read_forever
self._read_and_dispatch_next_frame()
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_comm/pydev_transport.py", line 37, in _read_and_dispatch_next_frame
direction, frame = self._read_frame()
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_comm/pydev_transport.py", line 45, in _read_frame
buff = readall(self._socket.recv, 4)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_comm/pydev_io.py", line 110, in readall
chunk = read_fn(sz - have)
TimeoutError: [Errno 60] Operation timed out
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_code_executor.py", line 112, in add_exec
self.finish_exec(more)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py", line 210, in finish_exec
return server.notifyFinished(more)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_comm/pydev_transport.py", line 226, in _req
return super(TSyncClient, self)._req(_api, *args, **kwargs)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/thrift.py", line 160, in _req
return self._recv(_api)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/thrift.py", line 172, in _recv
fname, mtype, rseqid = self._iprot.read_message_begin()
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/protocol/binary.py", line 372, in read_message_begin
self.trans, strict=self.strict_read)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/protocol/binary.py", line 164, in read_message_begin
sz = unpack_i32(inbuf.read(4))
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/transport/__init__.py", line 32, in read
return readall(self._read, sz)
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/third_party/thriftpy/_shaded_thriftpy/transport/__init__.py", line 20, in readall
"End of file reading from transport")
_shaded_thriftpy.transport.TTransportException: TTransportException(type=4, message='End of file reading from transport')
Try 2 Asyncio-
After reading the dataframe I tried -
async def async_ping(host):
proc = await asyncio.create_subprocess_shell(
f"/sbin/ping -c 1 {host} > /dev/null 2>&1",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
status = await proc.wait()
if status == 0:
return 'Alive'
else:
return 'Timeout'
async def async_main(hosts):
tasks1 = deque()
for host in hosts:
tasks1.append(asyncio.create_task(async_ping(host)))
return (t1 for t1 in await asyncio.gather(*tasks1))
start = time.perf_counter()
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
resp = loop.run_until_complete(async_main(df['IP Addresses'].to_list()))
loop.close()
finish = time.perf_counter()
df['Status'] = list(resp)
print(df)
print(f'Runtime: {round(finish-start,4)} seconds')
I ran into Blocking error -
Traceback (most recent call last):
File "~path/venv/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-6-2646fe9bd357>", line 26, in <module>
resp = loop.run_until_complete(async_main(df['IP Addresses'].to_list()))
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
return future.result()
File "<ipython-input-6-2646fe9bd357>", line 20, in async_main
return (t1 for t1 in await asyncio.gather(*tasks1))
File "<ipython-input-6-2646fe9bd357>", line 5, in async_ping
stderr=asyncio.subprocess.PIPE
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/subprocess.py", line 202, in create_subprocess_shell
stderr=stderr, **kwds)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1514, in subprocess_shell
protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/unix_events.py", line 190, in _make_subprocess_transport
**kwargs)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_subprocess.py", line 37, in __init__
stderr=stderr, bufsize=bufsize, **kwargs)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/unix_events.py", line 775, in _start
universal_newlines=False, bufsize=bufsize, **kwargs)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 800, in __init__
restore_signals, start_new_session)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1482, in _execute_child
restore_signals, start_new_session, preexec_fn)
BlockingIOError: [Errno 35] Resource temporarily unavailable
When I saw this question I wanted to try to make something that used the asyncio module to run pings concurrently. The below script runs my test IP addresses in ~7 seconds. When I run the same test IP address list synchronously it takes ~127 seconds. I used python version 3.8.2 and Windows 10 OS. Maybe it'll work for you.
import asyncio
import time
from collections import deque
import pandas as pd
async def async_ping(host, semaphore):
async with semaphore:
for _ in range(5):
proc = await asyncio.create_subprocess_shell(
f'C:\\Windows\\System32\\ping {host} -n 1 -w 1 -l 1',
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
status = await proc.wait()
if status == 0:
return 'Alive'
return 'Timeout'
async def async_main(hosts, limit):
semaphore = asyncio.Semaphore(limit)
tasks1 = deque()
for host in hosts:
tasks1.append(asyncio.create_task(
async_ping(host, semaphore))
)
return (t1 for t1 in await asyncio.gather(*tasks1))
host_df = pd.read_csv('ping_ip_dest.csv')
# set concurrent task limit
limit = 256
start = time.perf_counter()
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
resp = loop.run_until_complete(async_main(host_df['IP'].to_list(), limit))
loop.close()
finish = time.perf_counter()
host_df['Status'] = list(resp)
print(host_df)
print(f'Runtime: {round(finish-start,4)} seconds')
OUTPUT:
0 N. Virginia (Virginia, USA) 23.235.60.92 Alive
1 Dallas (Texas, USA) 69.162.81.155 Alive
2 Denver (Colorado, USA) 192.199.248.75 Alive
3 Miami (Florida, USA) 162.254.206.227 Alive
4 Minneapolis (Minnesota, USA) 207.250.234.100 Alive
5 Montreal (Canada) 184.107.126.165 Alive
6 New York (New York, USA) 206.71.50.230 Alive
7 San Francisco (California, USA) 65.49.22.66 Alive
8 Seattle (Washington, USA) 23.81.0.59 Alive
9 Washington DC (Virginia, USA) 207.228.238.7 Alive
10 Buenos Aires (Argentina) 131.255.7.26 Alive
11 Amsterdam (Netherlands) 95.142.107.181 Alive
12 Copenhagen (Denmark) 185.206.224.67 Alive
13 Frankfurt (Germany) 195.201.213.247 Alive
14 London (United Kingdom) 5.152.197.179 Alive
15 Madrid (Spain) 195.12.50.155 Alive
16 Paris (France) 51.158.22.211 Alive
17 Warsaw (Poland) 46.248.187.100 Alive
18 Johannesburg (South Africa) 197.221.23.194 Alive
19 Beijing (China) 47.94.129.116 Alive
20 Hong Kong (China) 103.1.14.238 Alive
21 Mumbai (India) 103.120.178.71 Alive
22 Shanghai (China) 106.14.156.213 Alive
23 Tokyo (Japan) 110.50.243.6 Alive
24 Brisbane 223.252.19.130 Alive
25 Sydney 101.0.86.43 Alive
26 Tel-Aviv (Israel) 185.229.226.83 Alive
27 Test 47.94.129.115 Timeout
Runtime: 3.1945 seconds
You can do it with a thread pool.
Updated for parameter to timeout ping after 1 second, chunksize 1, more threads and skipping intermediate shell - worked for a small number of IP addresses on my local machine duplicated to 14000 total. Wait time and chunksize may be the most important. By default, ping times out after 10 seconds and threadpool runs 14000/threadcount pings before returning to the main thread. Considering a timeout was hit when testing this code, the updates should be a good improvement.
from multiprocessing.pool import ThreadPool
import subprocess as subp
def ping_host(hostname):
# hostname = "10.0.0.10 #example
print(hostname)
if hostname != hostname:
return "No Hostname"
response = subp.run(["ping","-c", "1", "-W", "1", hostname], stdout=subp.DEVNULL,
stderr=subp.DEVNULL).returncode
# and then check the response...
if response == 0:
print(hostname, 'is up!')
return "Up"
else:
print(hostname, 'is down!')
return "Down"
# you can fiddle with pool size
with ThreadPool(processes=128) as t:
df['Host_Status'] = t.map(ping_host, df['IP Addresses'],
chunksize=1)
I've a problem when I have to display the results as a histogram with the plt.show() function, I need the function to be non-blocking because I need the return value of the principal funciont to make new calculations and show a new histogram.
(P.S. i'm using PyCharm ide and Python 3.6.7rc2 matplotlib 3.0.0)
This is the function in the code:
def plotHistStd(data_file, attribute, number, method):
original = copy.deepcopy(data_file)
modified = copy.deepcopy(data_file)
tmp_arr = []
tmp_arr2 = []
if method == 1:
for i in range(0, original.__len__()):
if original[i] > 0:
if number > 0:
tmp = log1p(original[i]+number)
tmp_arr.append(copy.deepcopy(original[i]))
tmp_arr2.append(copy.deepcopy(tmp.real))
else:
tmp = np.log1p(original[i]+number)
tmp_arr.append(copy.deepcopy(original[i]))
tmp_arr2.append(copy.deepcopy(tmp.real))
else:
tmp = np.log1p(original[i]+number)
tmp_arr.append(copy.deepcopy(original[i]))
tmp_arr2.append(copy.deepcopy(tmp.real))
modified[i] = tmp.real
elif method == 2:
for i in range(0, original.__len__()):
if original[i] > 0:
tmp2 = pow((original[i]), (1.0/number))
tmp_arr.append(copy.deepcopy(original[i]))
tmp_arr2.append(copy.deepcopy(tmp2.real))
else:
tmp2 = cm.exp(number*cm.log(original[i]))
tmp_arr.append(copy.deepcopy(original[i]))
tmp_arr2.append(copy.deepcopy(tmp2.real))
modified[i] = tmp2.real
v_max = max(tmp_arr)
v_min = min(tmp_arr)
v_max2 = max(tmp_arr2)
v_min2 = min(tmp_arr2)
v_max = max(v_max, v_max2)
v_min = min(v_min, v_min2)
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
n, bins, patches = ax1.hist(original, color="blue", bins=15, range=(v_min, v_max))
ax1.set_xlabel(attribute)
ax1.set_ylabel('Frequency')
n, bins, patches = ax2.hist(modified, color="red", bins=15, range=(v_min, v_max))
ax2.set_xlabel(attribute)
ax2.set_ylabel('Frequency')
plt.subplots_adjust(hspace=0.3)
plt.xticks(rotation=90)
plt.show() #need these non-blocking version
return modified
The function is called from the main window, developed in another Python class file.
I tried to insert plt.ion() after plt.show() but it does not work.
P.s. add the function in the main window that calls that indicates in precedence:
def apply_stdandardization(self):
if self.file[self.file.__len__() - 4:self.file.__len__()] != ".csv":
QtWidgets.QMessageBox.warning(QtWidgets.QWidget(),"Alert Message", "No CSV file was selected!")
else:
number = self.lineEdit_2.text()
index = self.comboBox_2.currentText()
std_method = 0
#data_file = pd.read_csv(self.file)
number = float(number)
try:
number = float(number)
except Exception:
QtWidgets.QMessageBox.warning(QtWidgets.QWidget(), "Alert Message",
"Insert only numeric value")
if self.rad_log.isChecked():
std_method = 1
elif self.rad_exp.isChecked():
std_method = 2
self.new_df = std_function(str(index), number, std_method)
EDIT:
I tried to insert plt.ion() before plt.show(), actually the program is not blocked, but the histogram window does not open correctly and if I click on it, the program crashes with the following errors:
Fatal Python error: PyEval_RestoreThread: NULL tstate
Thread 0x000016c0 (most recent call first):
File "C:\Python36\lib\threading.py", line 299 in wait
File "C:\Python36\lib\threading.py", line 551 in wait
File "C:\PyCharm\helpers\pydev\pydevd.py", line 128 in _on_run
File "C:\PyCharm\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 320 in run
File "C:\Python36\lib\threading.py", line 916 in _bootstrap_inner
File "C:\Python36\lib\threading.py", line 884 in _bootstrap
Thread 0x00000fb8 (most recent call first):
File "C:\PyCharm\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 382 in _on_run
File "C:\PyCharm\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 320 in run
File "C:\Python36\lib\threading.py", line 916 in _bootstrap_inner
File "C:\Python36\lib\threading.py", line 884 in _bootstrap
Thread 0x00000b28 (most recent call first):
File "C:\Python36\lib\threading.py", line 299 in wait
File "C:\Python36\lib\queue.py", line 173 in get
File "C:\PyCharm\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 459 in _on_run
File "C:\PyCharm\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 320 in run
File "C:\Python36\lib\threading.py", line 916 in _bootstrap_inner
File "C:\Python36\lib\threading.py", line 884 in _bootstrap
Current thread 0x00000b08 (most recent call first):
File "C:/Users/Enrico/PycharmProjects/PythonDataset/PDA.py", line 681 in <module>
File "C:\PyCharm\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18 in execfile
File "C:\PyCharm\helpers\pydev\pydevd.py", line 1135 in run
File "C:\PyCharm\helpers\pydev\pydevd.py", line 1735 in main
File "C:\PyCharm\helpers\pydev\pydevd.py", line 1741 in <module>
Process finished with exit code 255