Как чисто убить программу на питоне (которая включает в себя ROS и скрученный протокол) при нажатии Ctrl+c?

Я сделал узел ROS, который устанавливает соединение с клиентом, используя скрученный протокол python. Программа работает, как и ожидалось, но когда я пытаюсь убить программу с помощью Ctrl+c, появляется следующее сообщение об ошибке:

[server_send_command_ver3-4] эскалация до SIGTERM

Я включил часть моего кода ниже:

if __name__ == '__main__':
   try:
    #node initialization
    rospy.init_node('listen', anonymous = True)

    #publisher to publish message to clientconnection to display connection status on GUI
    connect = rospy.Publisher("status", String, queue_size = 10)
    connect.publish(" Lost Connection")

    #twisted protocol and listen at port 80
    factory = Factory()
    factory.protocol = NewFactory
    factory.clients = []  
    reactor.listenTCP(80, factory)
    reactor.run()

  except rospy.ROSInterruptException:
    pass

person Telepresence    schedule 16.05.2016    source источник


Ответы (2)


Хороший способ сделать это — использовать rospy.on_shutdown().

По сути, при реализации эта функция будет вызываться после запроса на отключение узла (например, нажатие Ctrl + C). В вашем случае вы можете закрыть свое соединение внутри этой функции и обработать все, что вам нужно, до полного отключения (в конечном итоге, например, reactor.close()).

Вот пример, взятый из здесь:

def myhook():
  print "shutdown time!"

rospy.on_shutdown(myhook)
person Vtik    schedule 16.05.2016

В rospy уже реализован обработчик сигналов (http://wiki.ros.org/rospy/Overview/Initialization%20and%20Shutdown) и должен нормально обрабатывать Ctrl+C (SIGINT).

Однако вы используете искривленный экземпляр, а reactor.run() является блокирующим вызовом. Сигнал, который вы посылаете, не замыкает скрученную нить. Поскольку программа не реагирует, rospy преобразует SIGINT в SIGTERM, чтобы принудительно закрыть программу.

Чтобы иметь возможность изящно закрыть вашу программу, вы можете либо реализовать хук на rospy, чтобы закрыть скрученный экземпляр (не уверен, что это сработает)

rospy.on_shutdown(reactor.stop)

или используйте библиотеку сигналов python для реализации обработчика SIGINT, который изящно закрывает все экземпляры в вашей программе (https://docs.python.org/2/library/signal.html)

person GSalazar    schedule 16.05.2016
comment
крючок rospy работает, но если убрать (): rospy.on_shutdown(reactor.stop) - person Javi; 23.07.2016