进程在异常后不会终止

时间:2014-02-12 15:53:09

标签: python serial-port pyserial

我让服务器运行,它应该与串行设备通信。我编写了一个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()

2 个答案:

答案 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)