我有一项服务,它Local System
有时会正常运行并且拒绝停止。
服务进程收到终止信号,进行清理,但由于存在错误,几个线程仍在运行。
SCM 向事件日志报告事件 ID 7011:
等待来自...服务的交易响应时超时(30000 毫秒)。
之后,管理控制台的服务窗口和 WMI 中服务显示为已停止。
但是如果服务没有终止,Windows 会如何处理它?我无法重新启动服务:旧服务运行的进程仍然锁定文件并绑定到端口。
我希望 Windows 能够终止没有响应的进程,但我找不到有关此的任何文档或设置。
30000 毫秒似乎取自HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ServicesPipeTimeout
(https://support.microsoft.com/en-us/help/839803/the-windows-trace-session-manager-service-does-not-start-and-event-id)。但是 30 秒后我只收到事件,进程仍然存在。
根据崩溃转储,主线程已终止,并且有几个线程正在等待套接字WaitForSingleObject
。
我们已经向供应商报告了该错误,他们正在尝试修复它。但主要的问题是如何终止此进程,是否有可能在不重启的情况下清除它。
答案1
您的服务可能已停止,但线程仍在运行,因此处于僵尸状态。众所周知,在 Windows 下,线程很难停止,如果它们卡在不可中断的系统调用中,那么它们绝对无法停止。
唯一的解决方案是更好地设计您的服务,以便可以发出信号让线程停止,并且该信号在服务的 OnStop() 方法中设置。
线程应该始终在所有系统调用上超时,并在触发超时时检查其停止条件。
另一种方法是使用 OnStop() 方法来thread.Abort()
停止线程。这通常不是一个好主意,因为不知道线程停止后会做什么,也不知道它正在修改的资源在中止后会处于什么状态(此外,这可能也是无效的)。