用C++编制Win32 Service (二)

名词:
  • Service Control Manager,服务控制管理器,简称SCM。
  • Service Control Dispatcher,服务控制发送器,简称SCD。
  • Service Process,服务进程,通常是一个Win32控制台应用程序(exe),由SCM负责启动。
  • Service Status,(当前)服务状态,当SCM向服务进程查询状态时,由服务进程回答当前的状态(如正在运行中、已暂停等)
一个服务进程被SCM启动后,应该尽快(30秒之内)调用StartServiceCtrlDispatcher这个API,通常由主线程来调用,因为一旦 调用成功,主线程将留在这个API里不再返回——直到服务进程中所有运行的服务均已终止,如果非要用另外一个线程来做这件事,主线程应该等待这个工作线程从StartServiceCtrlDispatcher返回(比方说用WaitForSingleObject什么的),私下里觉得这是没事找事)。
主线程在调用StartServiceCtrlDispatcher()时提供了SERVICE_TABLE_ENTRY数组,指明了每个Service的 回调函数入口(原型为ServiceMain(),由于是回调函数,所以只能是静态方法),由SCM发出一个启动请求到服务进程的SCD,由SCD创建一个新的线程来调用这个回调函数。
通常,ServiceMain()直接调用RegisterServiceCtrlHandlerEx ()来注册一个原型为HandlerEx()的回调函数(又是回调,又只能是静态方法,真讨厌)来处理控制请求(如请求启动、请求暂停等),处理完毕后再调用SetServiceStatus()来回答当前服务状态给SCM。由于SCM只有在等到Service报告了一个SERVICE_RUNNING状 态后,才认为该Service成功启动,在此之前SCM将不应答系统的其他请求,所以服务进程尽可能快地提交这个状态报告。
前面说的两个 回调函数必须是类的静态方法(我把这两个静态方法放在ServiceApplication类而不是ServiceBase中),所以必须有一个机制(根 据服务名)查找到相应的ServiceBase对象实例,前几天架构的时候是把ServiceApplication设计成一个Singleton,现在发现真正需要具有惟一实例的东西不过就是保存所有ServiceBase对象指针的容器,以及在多线程下访问该容器的一个临界区(或互斥元等线程同步对象),所以,我决定把这个容器及线程同步对象提炼成一个新的辅助类,确保对容器的访问都是线程安全(其实由于ServiceBase在运行时刻不会再更改容器的内容,而只是读取,所以线程同步对象似乎不一定必要),且是一个状态成员,这样在回调函数(静态方法)中就可以方便访问这个容器了,同时由于最经常的动作是根据服务名查找对象实例指针,所以用STL的map容器似乎是比较合适的,另外,对于线程同步对象,我通常喜欢用临界区,因为它大部分时间是工作在用户方式而不是内核方式里。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值