程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> Windows服務編寫原理及探討(4)

Windows服務編寫原理及探討(4)

編輯:vc教程

(四)一些問題的討論

前面幾章的內容都是服務的一些通用的編寫原理,但裡面隱含著一些問題,編寫簡單的服務時看不出來,但遇到復雜的應用就會出現一些問題,所以本章就是用來分析、解決這些問題的,適用於高級應用的開發人員。我這一章的內容都是經過實驗得到的,很有實際意義。

我在第一章裡面就說過,是由一個服務的主線程執行CtrlHandler函數,它將收到各種控制命令,但是真正處理命令,執行操作的是ServiceMain的線程。現在,當一個SERVICE_CONTROL_STOP到達之後,你作為一個開發者,要怎樣停止這個服務?在我看過的一些源代碼裡,大部分只是簡單的調用TerminateThread函數去強行殺掉服務進程。但應該稍稍有點線程的常識就應該知道TerminateThread函數是可用的調用中最為糟糕的一個,服務線程將得不到任何機會去做應該的清理工作,諸如清除內存、釋放核心對象,Dlls也得不到任何線程已經被毀的通知。

所以停止服務的適當方法是以某種方式激活服務線程,讓它停止繼續提供服務功能,然後執行完當前操作和清除工作後返回。這就表示你必須在CtrlHandler線程和ServiceMain線程之間執行適當的線程通信。現在已知的最好的內部線程通信機制是I/O Completion Port(I/O 完成端口),假如你編寫的是一個大型的服務,需要同時處理為數眾多的請求,並且運行在多處理器系統上面,這個模型就可以提供最佳的系統性能。但也正因為它的復雜性較高,在小規模的應用上面不值得花費很多的時間和精力,這時作為開發者可以適當的選取其它的通信方式,諸如異步過程調用隊列、套接字和窗口消息,以適應實際情況。

開發服務時的另外一個重要問題就是調用SetServiceStatus函數時的所有狀態報告問題。很多的服務開發者為了在什麼時候調用SetServiceStatus的問題而常常產生爭論,一般推薦的方法就是:先調用SetServiceStatus函數,報告SERVICE_STOP_PENDING狀態,然後將控制代碼傳給服務線程或者再建立一個新的線程,讓它去繼續執行操作,當該線程即將執行完操作之前,再由它將服務的狀態設置成SERVICE_STOPPED,然後服務正好停止。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved