2012-12-05 37 views
0

我們應永遠運行,並儘快啓動系統時開始的launchd守護程序,因此它的plist我們說:OSX,關停的launchd守護下來,網絡不可用

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

一切直到系統關閉爲止。代理需要通過HTTP向遠程服務器通知正在關閉的系統。系統向代理髮送SIGTERM就好了,代理能夠處理它。但是,當它收到SIGTERM時,DNS(或者可能是整個網絡子系統)已經關閉,並且無法將狀態發送到服務器,因爲它無法解析其名稱。所有的網絡功能都失敗了,所以我懷疑網絡連接已經關閉。在Linux上,這由SNN/KMM符號鏈接解決,NN = 99和MM = 00。但是,在OSX上明確表示launchd守護進程沒有任何優先級。那麼我們如何才能讓OSX在關閉DNS /網絡之前向我們的守護進程發送SIGTERM?

我很快就注意到爲系統關閉事件註冊監聽程序的能力,因爲程序可以註冊自己以監聽功耗模式更改(即睡眠),但是有幾個消息來源告訴我這是不可能的 - Receiving power notifications (especially shutdown) on Mac OSX

回答

0

我不得不懷疑會有一個分佈式通知,通知該應用程序,所以我寫了一個小的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當對接被按下。

現在,當然您不會知道關閉是否會實際發生,應用程序可以取消關閉。不過,您可能也會收到通知。

+0

對不起,我沒有提到 - 這是C++應用程序,所以我們只能調用C中提供的Mac API,不支持Obj-C。正如我在我的問題提供的URL中讀到的,守護進程不會收到關於系統關閉的通知。無論如何,我們會收到SIGTERM關閉的守護進程通知,問題更多的是影響系統組件順序的下降。但是昨天晚上,我似乎解決了這個問題 - 當代理獲取SIGTERM時,只有DNS關閉,網絡仍然存在。我們在上一次成功會話中緩存服務器的IP地址,並在通知關閉時使用它。 –

+0

那麼我的觀點是,當關機過程開始時,你會得到這個通知,這將在你的守護進程發送SIGTERM之前。您也可以使用Core Foundation(C API)完成上述操作。 https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html。很高興你找到了解決方案! – joerick