我让服务器运行,它应该与串行设备通信。我编写了一个init.d脚本,如果由于某种原因崩溃,它应自动重启服务器。但是要实现这一点,python脚本必须正确终止。不幸的是,如果引发异常(例如,如果我拔掉我的串行设备),我的线程就会卡住,并且永远不会终止。
这是错误:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "RPiQuadroServer.py", line 87, in recv_thr
while pySerial.inWaiting() > 0:
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 431, in inWaiting
s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
IOError: [Errno 5] Input/output error
这就是代码。我删除了一些不重要的功能..
# Make this Python 2.7 script compatible to Python 3 standard
from __future__ import print_function
# For remote control
import socket
import json
import serial
# For sensor readout
import logging
import threading
# For system specific functions
import sys
from time import *
# Create a sensor log with date and time
layout = '%(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(filename='/tmp/RPiQuadrocopter.log', level=logging.INFO, format=layout)
# Socket for WiFi data transport
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_sock.bind(('0.0.0.0', 7000))
client_adr = ""
# Thread lock for multi threading
THR_LOCK = threading.Lock()
#pySerial
pySerial = 0
# These functions shall run in separate threads
# recv_thr() is used to catch sensor data
def recv_thr():
global client_adr
ser_line = ""
while True:
# Lock while data in queue to get red
THR_LOCK.acquire()
while pySerial.inWaiting() > 0:
try:
# Remove newline character '\n'
ser_line = pySerial.readline().strip()
except serial.SerialTimeoutException as e:
logging.error("Read timeout on serial port '{}': {}".format(com_port, e))
return # never ends..
else:
try:
p = json.loads(ser_line)
except (ValueError, KeyError, TypeError):
# Print everything what is not valid json string to console
#print ("JSON format error: %s" % ser_line)
logging.debug("JSON format error: " + ser_line)
else:
logging.info(ser_line)
if client_adr != "":
bytes = udp_sock.sendto(ser_line, client_adr)
THR_LOCK.release()
# Main program for sending and receiving
# Working with two separate threads
def main():
# Start threads for receiving and transmitting
recv=threading.Thread(target=recv_thr)
recv.start()
# Start Program
bInitialized, pySerial = init_serial()
if not bInitialized:
print ("Could not open any serial port. Exit script.")
sys.exit()
main()
答案 0 :(得分:1)
不是你的程序正在终止,只有你自己的一个帖子以异常终止。
您需要检查自己该线程是否仍在运行,如果是,则终止。
除了 polling 的radu.ciorba提议之外,您还可以捕获线程中的所有异常,并且如果它因异常而失败,请将SIGTERM发送到您的进程;这将终止所有线程,从而终止进程。
使用os.kill(os.getpid(), 15)
并将其放在一般的except
子句中:
def recv_thr(...): # add your arguments here
try:
... # add your code here
except:
os.kill(os.getpid(), 15)
答案 1 :(得分:0)
您可以检查线程是否仍处于活动状态,如果不是,则退出:
import time
import sys
import threading
def spam():
raise AssertionError("spam")
t = threading.Thread(target=spam)
r = t.start()
while 1:
time.sleep(.5)
if not t.is_alive():
sys.exit(1)