[英]Process not terminating after exception
我让服务器运行,该服务器应与串行设备通信。 我编写了一个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()
不是您的程序正在终止,而是您的线程正在终止,但有异常。
您需要检查自己,如果该线程仍在运行,请终止。
除了radu.ciorba提议对线程进行轮询之外 ,您还可以捕获线程中的所有异常,如果由于异常而失败,则将SIGTERM发送给您的进程。 这将终止所有线程,从而终止进程。
os.kill(os.getpid(), 15)
请使用os.kill(os.getpid(), 15)
并将其放在一般的except
子句中:
def recv_thr(...): # add your arguments here
try:
... # add your code here
except:
os.kill(os.getpid(), 15)
您可以检查线程是否仍然存在,如果不是,则退出:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.