首页 > 解决方案 > 如何在程序结束时关闭python进程

问题描述

我无法在程序结束时关闭在进程中正确运行的串行连接。(在 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

标签: python-3.xpyserial

解决方案


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

所以你有几个选择:

  • catchKeyboardInterrupt并使用它来退出 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)
    

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


推荐阅读