在MacOS上运行Swift:在后台应用终止时运行代码

时间:2019-10-04 16:48:50

标签: swift macos kill-process sigint sigterm

我正在编写一个Mac应用程序,该程序在后台作为守护程序运行。如何检测应用程序何时被杀死并运行一些清除代码?我曾尝试捕获SIGTERMSIGINTSIGKILL之类的信号,但是我的应用程序结构似乎与此有关。

这是我的应用程序从主线程开始的基本流程:

func signalHandler(signal: Int32) { ... }

let signals = [SIGINT, SIGTERM, SIGKILL]
for sig in signals {
    signal(sig, signalHandler)
}

// code to kick off background execution that will occasionally need to run some stuff on the main thread

RunLoop.current.run() // SIGTERM shows up in Xcode on this line, signalHandler not called

如果我使用Xcode的停止按钮停止应用程序或从活动监视器强制退出,则该应用程序将以退出代码9(SIGKILL)退出。如果我从活动监视器中选择“退出”,则应用程序会收到一个SIGTERM,但不会调用该处理程序……Xcode仅突出显示RunLoop行并说Thread 1: signal SIGTERM。 / p>

没有RunLoop行,我的应用程序将几乎立即停止,但是我需要保持它的生命。同时,我在想这行可能会阻塞主线程并阻止信号处理程序运行。有没有什么办法可以解决我的应用终止问题?

1 个答案:

答案 0 :(得分:3)

一些注意事项:

  • SIGKILL cannot be caught
  • 如果连接了调试器,它将拦截信号处理程序,而不是让程序流过;可以找到一种解决方法here

尝试打印信号并从命令行启动程序


func signalHandler(signal: Int32) {
    print("Caught signal \(signal)")
}

Ctrl + C 打印Caught signal 2

通过Quit(而非Force Quit)从“活动监视器”终止该过程将打印Caught signal 15