Windows shutdown transition

分為 UserSession/SystemSession/KernelShutdown 等三個 phase。



UserSession phase


在這個階段,csrss.exe (Client/Server Runtime Server Subsystem) 會對所有在 session ID 1 (user session) 上執行的 UI app 發出 WM_QUERYENDSESSION and WM_ENDSESSION 訊息。假如 user 是自己由 start menu 中按 shutdown 的話,5 秒後有任何 app 卡住,Windows 會顯示一個視窗告訴 user 有哪些 app 需要被關掉。user 可以選擇強制關掉它們。而對於 console app,Windows 會對 console control handler 送 CTRL_LOGOFF_EVENT 並且一樣等待 5 秒。


假如 user 選擇強制關掉 app,系統會給 0.25 秒的時間讓 app 處理 WM_QUERYENDSESSION 訊息,0.5 秒的時間處理 WM_ENDSESSION。之後便會關掉所有未關掉的 app。


另外有一種叫 system-forced shutdown,這是 user 執行 shutdown.exe 或透過 Windows API 來關機的情況。這情形下 Windows 不會提示使用者任何的 dialog 而會在 5 秒後直接強制關掉 blocked app。像 Windows Update 後的重開機便是屬於此種 shutdown。


以上可知,app 是否能夠快速地回應 WM_QUERYENDSESSION and WM_ENDSESSION 訊息對 shutdown performance 有巨大的影響。因此 app developer 應該注意以下事項:


* 避免在 shutdown 時做 data flush 或將此影響減到最小(應該在 app 中定時 flush)
* 避免在程式初始時做 data flush
* 避免在 shutdown 時做 registry flush
* 避免在 shutdown 時做不必要的 network access


SystemSession phase


這個部份分為兩個 subphase:Preshutdown/Shutdown notification。


Preshutdown notification:Windows 一個一個地 shutdown 註冊過 preshutdown notification 的 service。在這兒 ordered services,也就是 service 有被設定 shutdown 順序的,會比 non-ordered services 要來得早關掉。


Shutdown notification:同時關掉所有註冊 shutdown notification 的 service。


假如經過 20 秒(Vista)或 12 秒(Win7)後所有的 service 還未完全關掉,系統會不管它們而繼續進行 shutdown。因此對 shutdown notification 的快速回復便是影響關機的關鍵。一個 service 應該在它收到 shtudown notification 後馬上將自己的狀態設成 STOP_PENDING(讓控制權交回給 SCM),並且儘快進入 stopped state。如果有任何的 service 無回應的話,SystemSession phase 的時間就會被拉長到 20 秒(Vista)或 12 秒(Win7)。


KernelShutdown phase


最後要關掉的當然就是 device driver 了。


Summary


* 使用 WPT
* 沒必要的話不要註冊 SERVICE_CONTROL_PRESHUTDOWN and SERVICE_CONTROL_SHUTDOWN
* 如果 service 一定要收到 notification,儘快回覆給 SCM
* 所有 app 應該儘快處理 WM_QUERYENDSESSION and WM_ENDSESSION 訊息
* 在 shutdown 途中儘量減少 CPU/Disk/Network 的活動


留言

熱門文章