【问题标题】:OSX, shutting launchd daemon down and network is not availableOSX,关闭启动守护程序并且网络不可用
【发布时间】:2012-12-05 18:55:16
【问题描述】:

我们已经启动了应该永远运行并在系统启动后立即启动的守护程序,因此在它的 plist 中我们说:

<key>KeepAlive</key> <true/>

在系统关闭之前一切正常。代理需要通过 HTTP 通知远程服务器系统正在关闭。系统将 SIGTERM 发送给代理就好了,代理能够处理它。但是,当它收到 SIGTERM 时,DNS(或者可能是整个网络子系统)已经关闭,并且它无法将状态发送到服务器,因为它无法解析其名称。所有网络功能都失败了,所以我怀疑网络已经关闭。在 Linux 上,这由具有 NN=99 和 MM=00 的 SNN/KMM 符号链接解决。然而,在 OSX 上明确表示 launchd 守护进程没有任何优先级。那么我们如何让 OSX 在关闭 DNS/网络之前向我们的守护进程发送 SIGTERM?

我很快研究了为系统关闭事件注册监听器的能力,因为程序可以注册自己以监听电源模式更改(即睡眠),但是一些消息来源告诉这也是不可能的 - Receiving power notifications (especially shutdown) on Mac OSX

【问题讨论】:

    标签: macos launchd


    【解决方案1】:

    我怀疑会有一个分布式通知通知应用程序,所以我写了一个小 Obj-C 应用程序......

    #import <Foundation/Foundation.h>
    
    int main(int argc, char *argv[])
    {
        @autoreleasepool
        {
            [[NSDistributedNotificationCenter defaultCenter]
             addObserverForName: nil
             object: nil
             queue: [NSOperationQueue mainQueue]
             usingBlock: ^(NSNotification *notification) {
                NSLog(@"Got a notification %@", notification);
            }];
    
            [[NSRunLoop mainRunLoop] run];
        }
    }
    

    我收到了这些通知

    05/12/2012 19:17:12.044 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98e04900 {name = com.apple.logoutInitiated; object = 501}
    05/12/2012 19:17:22.376 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98c0c580 {name = com.apple.shutdownInitiated; object = 501}
    05/12/2012 19:17:22.388 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98c0b8f0 {name = com.apple.logoutContinued; object = 501}
    
    • com.apple.logoutInitiated 对应于关闭对话框的打开,并且
    • 按下按钮时收到com.apple.shutdownInitiated

    现在,您当然不会知道关闭是否真的会发生,一个应用程序可以取消关闭。不过,您可能也会收到通知。

    【讨论】:

    • 抱歉,我没有提到 - 这是 C++ 应用程序,所以我们只能调用 C 中可用的 Mac API,不能调用 Obj-C。正如我在问题中提供的 URL 中所读到的,守护程序不会收到系统关闭的通知。无论如何,我们被告知守护程序已被 SIGTERM 关闭,问题更多是关于影响系统组件关闭的顺序。但是昨天晚上我似乎解决了这个问题 - 当代理获得 SIGTERM 时,似乎只有 DNS 关闭,网络仍然正常。我们在最后一次成功会话时缓存服务器的 IP 地址,并在通知关闭时使用它。
    • 好吧,我的意思是,当关闭进程开始时,您会收到此通知,这将是在您的守护进程被发送 SIGTERM 之前。您也可以使用 C API 的 Core Foundation 执行上述操作。 developer.apple.com/library/mac/#documentation/CoreFoundation/… 。很高兴您找到了解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多