A T*_*hka 1 sigint grand-central-dispatch swift
使用这个答案作为参考,我试图在我的 swift linux 脚本中实现一个信号处理程序,它将使程序保持活动状态直到 Ctrl-C,然后在收到 SIGINT 时运行一些清理。使用该答案中的代码在主函数中效果很好:
import Dispatch
import Foundation
signal(SIGINT, SIG_IGN) // // Make sure the signal does not terminate the application.
let sigintSrc = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
sigintSrc.setEventHandler {
print("Got SIGINT")
// ...
exit(0)
}
sigintSrc.resume()
dispatchMain()
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将信号处理程序移动到一个函数中,如下所示:
public func registerSigint() {
signal(SIGINT, SIG_IGN)
let sigintSrc = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
sigintSrc.setEventHandler {
print("Got SIGINT")
exit(0)
}
sigintSrc.resume()
}
Run Code Online (Sandbox Code Playgroud)
...
registerSigint()
dispatchMain()
Run Code Online (Sandbox Code Playgroud)
程序在 CTRL-C SIGINT 上无限期挂起。为什么这表现不同?
DispatchSource是一个类,即引用类型。在您的第二个示例中,调度源存储在函数的局部变量中。一旦函数返回,不存在对调度源的引用,因此它被取消和释放。
只要程序运行,您就需要将调度源存储在它所在的某个地方,例如在全局变量中:
public func registerSigint() -> DispatchSourceSignal {
signal(SIGINT, SIG_IGN)
let sigintSrc = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main)
sigintSrc.setEventHandler {
print("Got SIGINT")
exit(0)
}
sigintSrc.resume()
return sigintSrc
}
let source = registerSigint()
dispatchMain()
Run Code Online (Sandbox Code Playgroud)