我正在开发一个应该作为服务运行的Windows应用程序,我使用此出版物:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb540475(v=vs.85).aspx
但它不是线程不安全的吗?如果我理解正确,则从SvcInit和SvcCtrlHandler调用ReportSvcStatus(使用全局变量gSvcStatus和gSvcStatusHandler),它在不同的线程中运行。但它没有采取任何锁定...... 那么为什么使用这段代码是安全的呢?
答案 0 :(得分:1)
代码接近线程安全,因为主线程和回调线程在不同时间使用全局变量 - 服务启动期间的主线程,仅在服务运行时使用回调线程,以及服务关闭时的主线程。
但是,在处理停止请求期间,第二次从回调线程调用ReportSvcStatus
可能会与发出停止事件后主线程中对ReportSvcStatus
的调用冲突。在实践中,主线程可能不会足够快地响应事件以使其成为问题;我不确定。我也不确定第二次通话的目的是什么;这似乎是多余的。删除它应该消除这种竞争条件。
我相信如果在调用SetServiceStatus
之前服务状态设置为运行后立即收到停止请求,则还存在潜在的竞争条件,尽管这在实践中更不可能发生。这可以通过用临界区保护ReportSvcStatus
的内容来消除。
也可能存在一些多核(内存缓存)问题 - 这些都是更微妙的推理。我相信在ReportSvcStatus
中使用关键部分也会解决这些问题,至少在现有的CPU平台上是这样。