2014-02-12 72 views
0

我讓服務器運行,它應該與串行設備通信。我寫了一個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() 

回答

1

不是你的程序終止,只是你的一個線程與終止一個例外。

您需要檢查自己該線程是否仍在運行,如果有,終止。

除了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) 
+0

對不起,您的代碼有效,謝謝 – dgrat

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) 
+0

它仍然掛在上方的例外。完全奇怪! – dgrat

相關問題