如何在程序结束时关闭python进程

时间:2019-01-24 09:21:41

标签: python-3.x pyserial

在程序结束时,我无法关闭在进程中正确运行的串行连接。 (在Windows / VSCode和Ctrl-C上)

在程序下次启动时,我会收到一条错误消息,并且大多数时间该端口已经打开。

我必须先完成运行过程吗?

class serialOne(Process):
    def __init__(self, serial_port, debug, baudrate=57600, timeout=1):
    ...

    def terminate(self):
        print("close ports")
        self.active = False
        self.ser.close()

    def run(self):
        while self.active:
            self.initCom()
            self.readCom()
            time.sleep(0.005)

    def main():
        global processList
        global debug

        while True:
            if debug == True:
                print("main")
            time.sleep(1.0)

        for process in processList:
            process.terminate()

和我的主要人:

def main():
    global processList
    global debug

    while True:
        if debug == True:
            print("main") # actually doing nothing
        time.sleep(1.0)

    for process in processList:
        process.terminate()

那是错误消息:

Process serialOne-1:
Traceback (most recent call last):
  File "C:\Users\dgapp\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
Traceback (most recent call last):
  File "e:\_python\rfid_jacky\simple_multiprocess_rfid_02.py", line 129, in run
    time.sleep(0.005)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\ptvsd_launcher.py", line 45, in <module>
KeyboardInterrupt
    main(ptvsdArgs)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\__main__.py", line 265, in main
    wait=args.wait)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\__main__.py", line 258, in handle_args
    debug_main(addr, name, kind, *extra, **kwargs)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 45, in debug_main
    run_file(address, name, *extra, **kwargs)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 79, in run_file
    run(argv, addr, **kwargs)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 140, in _run
    _pydevd.main()
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1925, in main
    debugger.connect(host, port)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1283, in run
    return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1290, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "c:\Users\dgapp\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\_pydev_imps\_pydev_execfile.py", line 25, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "e:\_python\rfid_jacky\simple_multiprocess_rfid_02.py", line 161, in <module>
    main()
  File "e:\_python\rfid_jacky\simple_multiprocess_rfid_02.py", line 140, in main
    time.sleep(1.0)
KeyboardInterrupt

2 个答案:

答案 0 :(得分:1)

当您按下Ctrl+C时,会抛出KeyboardInterrupt异常,并中断您的无限睡眠循环。但是,由于您没有捕获到此异常,因此永远不会调用此循环(带有process.terminate())后的代码 ,这可能会导致问题。

因此,您有几种选择:

  • 捕获KeyboardInterrupt并使用它退出inifite循环:

    def main():
        global processList
        global debug
    
        try:
            while True:
                if debug == True:
                    print("main") # actually doing nothing
                time.sleep(1.0)
        except KeyboardInterrupt:
            pass
    
        for process in processList:
            process.terminate()
    

    这是简单易懂的

  • 注册将在程序退出时运行的退出处理程序:

    import atexit
    
    @atexit.register
    def shutdown():
        global processList
    
        for process in processList:
            process.terminate()
    
    def main():
        global debug
    
        while True:
            if debug == True:
                print("main") # actually doing nothing
            time.sleep(1.0)
    

    哪一个更可靠,因为即使您的进程被另一个信号终止,它也可以工作。

答案 1 :(得分:0)

KeyboardInterrupt在用户按下中断键时发生。

一个简单的解决方案是捕获异常:

while True:
    if debug == True:
        print("main") # actually doing nothing

    try:
        # do your things
    except KeyboardInterrupt:
        print("program was interrupted by user")
        break

您还可以使用finally关键字正确结束程序:

try:
    while True:
        # do your things    
except KeyboardInterrupt:
    print("program was interrupted by user")
    break
finally:
    close()  # this will always happen, even if an exception was raised