在macOS中用Swift监控进程:能否获取特定进程终止的通知?
在macOS Swift中监听特定进程终止的实现方案
可以实现,下面介绍两种常用的方法来监听系统内特定进程的终止事件:
方法一:使用kqueue监听高效事件(推荐)
kqueue是BSD系统提供的高效事件通知机制,通过EVFILT_PROC过滤器可以直接监听进程的退出事件,无需轮询,性能更优。
实现步骤:
- 获取目标进程的PID(可通过进程名遍历系统进程获取,比如用
proc_listpids实现匹配逻辑) - 创建kqueue实例,添加进程退出监听事件
- 启动监听循环,处理退出事件
Swift代码示例:
import Darwin func monitorProcessExit(pid: pid_t) { let kq = kqueue() guard kq != -1 else { print("创建kqueue失败: \(strerror(errno))") return } defer { close(kq) } var event = kevent() EV_SET(&event, UInt(pid), EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT, 0, nil) var events = [kevent](repeating: kevent(), count: 1) while true { let eventCount = kevent(kq, &event, 1, &events, 1, nil) guard eventCount != -1 else { print("Kevent错误: \(strerror(errno))") break } if eventCount > 0 { print("进程 \(pid) 已终止") break } } } // 使用示例:监听PID为1234的进程 // monitorProcessExit(pid: 1234)
方法二:定时轮询进程状态(简单易实现)
如果不需要极致性能,也可以通过定时检查进程是否存在来判断是否终止,适合快速实现的简单场景。
实现步骤:
- 编写函数判断进程是否存活
- 使用定时器定期检查进程状态
Swift代码示例:
import Darwin import Dispatch func isProcessAlive(pid: pid_t) -> Bool { var info = proc_bsdinfo() let result = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &info, MemoryLayout<proc_bsdinfo>.size) return result > 0 } func monitorProcessWithPolling(pid: pid_t, interval: TimeInterval = 1.0) { let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()) timer.schedule(deadline: .now(), repeating: interval) timer.setEventHandler { if !isProcessAlive(pid: pid) { print("进程 \(pid) 已终止") timer.cancel() } } timer.resume() } // 使用示例:每1秒检查一次PID为1234的进程 // monitorProcessWithPolling(pid: 1234)
注意事项:
- 权限问题:如果目标进程属于其他用户或系统级进程,可能需要root权限才能正常获取进程信息
- 进程名匹配:若不知道目标PID,可通过
proc_listpids遍历系统进程,根据进程名匹配获取对应PID(需额外实现遍历匹配逻辑)
内容的提问来源于stack exchange,提问作者Lupurus
相关产品推荐
相关产品推荐

