我有一个python程序,该程序运行一个线程以从串行端口获取数据。在线程冻结之前,该程序可以正常运行大约1个小时,而我倾向于反复获取最后一组值(在冻结发生之前获取的值)。 是什么原因可能导致线程冻结?
import pynmea2
import serial
import pandas as pd
import threading
import multiprocessing
from datetime import datetime
from dateutil import parser
from analyser import Analysis
import os
import logging
import time
gps_data = {}
arduino_data = {}
def read_serial_arduino(port, baud, ard_key_list):
ser = serial.Serial()
ser.port = port
ser.baudrate = baud
# ser.bytesize = serial.EIGHTBITS #number of bits per bytes
# ser.parity = serial.PARITY_NONE #set parity check: no parity
# ser.stopbits = serial.STOPBITS_ONE #number of stop bits
# ser.timeout = None #block read
# ser.timeout = 0 # non blocking read
ser.xonxoff = False # disable software flow control
ser.rtscts = False # disable hardware (RTS/CTS) flow control
ser.dsrdtr = False # disable hardware (DSR/DTR) flow control
ser.writeTimeout = 2 # timeout for write
try:
ser.open()
except Exception as e:
print("error open serial port: " + str(e))
exit()
if ser.isOpen():
try:
int_index = [0, 4, 5, 6]
float_index = [1, 2, 3, 6, 7, 8]
while True:
c = ser.readline().decode("ascii", "ignore").strip().split(",")
if len(c) > 1:
global arduino_data
for i in int_index:
c[i] = int(c[i])
for j in float_index:
c[j] = float(c[j])
arduino_data = dict(zip(ard_key_list, c))
ser.close()
except Exception as e1:
print("error...Arduino: " + str(e1))
else:
print("cannot open serial port ")
exit()
def read_serial_gps(port, baud):
ser = serial.Serial()
ser.port = port
ser.baudrate = baud
# ser.bytesize = serial.EIGHTBITS #number of bits per bytes
# ser.parity = serial.PARITY_NONE #set parity check: no parity
# ser.stopbits = serial.STOPBITS_ONE #number of stop bits
# ser.timeout = None #block readq
# ser.timeout = 0 # non blocking read
ser.xonxoff = False # disable software flow control
ser.rtscts = False # disable hardware (RTS/CTS) flow control
ser.dsrdtr = False # disable hardware (DSR/DTR) flow control
ser.writeTimeout = 2 # timeout for write
try:
ser.open()
except Exception as e:
print("error open serial port: " + str(e))
exit()
if ser.isOpen():
try:
while True:
c = ser.readline().decode('ascii', "ignore")
# with lock:
if len(c) > 0:
if c.__contains__('$GNRMC'):
msg = pynmea2.parse(c)
global gps_data
gps_data["Latitude"] = round(float(msg.lat[:2]) + float(msg.lat[2:]) / 60, 6)
gps_data["Longitude"] = round(float(msg.lon[1:3]) + float(msg.lon[3:]) / 60, 6)
gps_data["GPS_Speed"] = msg.spd_over_grnd * 1.852
gps_data["Timestamp"] = parser.parse(str(msg.datestamp) + ' ' + str(msg.timestamp))
# gps_data["Timestamp"] = msg.timestamp
ser.close()
except Exception as e1:
print("error communicating GPS...: " + str(e1))
else:
print("cannot open serial port GPS ")
exit()
def serial_grab_analyse():
"""
This Process grabs Serial data from two serial ports and then packs them into a dictionary and appends to a dataframe
the Data frame is then sent further for analysis.
:return: No return
"""
ard_data_key_list = ["GyroX","GyroY", "GyroZ", "APot", "BPot", "CPot"]
# Thread to grab data from the GPS serially
g = threading.Thread(target=read_serial_gps,
args=('COM3', 9600,))
g.daemon = True
g.start()
# Thread to grab data from Arduino Serially
y = threading.Thread(target=read_serial_arduino, args=(
'COM8', 115200, ard_data_key_list,))
y.daemon = True
y.start()
df = pd.DataFrame(columns=ard_data_key_list + ['Latitude', 'Longitude', 'GPS_Speed', 'Timestamp'])
first_time_stamp = None
flag_time_stamp = None
# This while loop keeps the above threads running.
data_analyser = Analysis()
while True:
try:
captured_data = {**arduino_data, **gps_data}
# appending a constant speed for testing
# captured_data['Speed'] = 0.167
print(captured_data)
time.sleep(0.02)
df = df.append(captured_data, ignore_index=True)
df.dropna(inplace=True)
print(df)
if len(df.index):
speed_var.value = int(float(captured_data["Speed"]))
if not first_time_stamp:
flag_time_stamp = first_time_stamp = df["Timestamp"].iloc[0]
if (df["Timestamp"].iloc[-1] - flag_time_stamp).seconds >= 60:
flag_time_stamp = df["Timestamp"].iloc[-1]
data_analyser.analyse(df, first_time_stamp)
print(g)
if terminate.value == 1:
exit(0)
break
except Exception as e:
print(e)
if __name__ == "__main__":
# Shared value between the two processes to terminate the p2 process when p1 is terminated
p1 = multiprocessing.Process(target=serial_grab_analyse)
p1.start()
我正在尝试从两个串行端口(arduino微控制器和GPS设备)读取数据。为此,有两个线程可以无限期运行,我将其放置为一个进程,因为还有另一个进程从网络摄像头获取图片(该进程不在代码段中)。问题在于,连续运行40-50分钟后,GPS读取线程几乎挂起。