我有一项服务需要关闭和更新。我在两种不同的情况下遇到了困难:
我有一些线程睡了很长时间。显然我不能等他们醒来才能完成关闭服务。我有一个想法是使用一个AutoResetEvent,当一个控制器线程在睡眠间隔结束时(通过每两秒检查一次)来设置,并在OnClose时间立即触发它。是否有更好的方法来促进这一点?
我有一个线程调用阻塞方法调用(我无法修改)。你如何表示这样一个线程停止?
答案 0 :(得分:3)
我不确定我是否正确理解了您的第一个问题,但您是否考虑过使用WaitForSingleObject
作为Sleep
的替代方案?您可以指定超时以及要等待的对象,因此如果您希望它提前唤醒,只需发出信号对象。
“呼叫阻塞线程”究竟是什么意思?或者你只是意味着阻止电话?通常,没有办法在没有强制终止线程的情况下中断线程。但是,如果呼叫是系统调用,则可能是通过使呼叫失败来返回控制的方法,例如。取消I / O或关闭相关句柄。
答案 1 :(得分:2)
对于1.您可以使用SleepEx而不是Sleep来使线程进入可中断的休眠状态。一旦他们得到这个关机启动(使用QueueUserApc从终止逻辑启动),您可以使用SleepEx的返回代码检测到它并相应地终止这些线程。这类似于使用WaitForSingleObject的建议,但是您不需要另一个用于终止关联线程的每个线程句柄。
如果是,则返回值为零 指定的时间间隔已过期。
返回值为WAIT_IO_COMPLETION 如果函数返回由于一个或 更多I / O完成回调 功能。这只有在发生时才会发生 bAlertable为TRUE,如果是线程 称为SleepEx功能的是 调用的同一个线程 扩展I / O功能。
对于2.,这是一个艰难的,除非您有权访问该线程中使用的某些资源,这些资源可能导致阻塞调用以调用线程可以干净地处理它的方式中止。您可能只需使用TerminateThread实现使用极端偏见来杀死该线程的代码(可能这应该是您在退出流程之前做的最后一件事)并查看测试中会发生什么。
答案 2 :(得分:1)
简单可靠的解决方案是终止服务流程。毕竟,一个进程是操作系统的内存安全抽象,所以你可以安全地终止它而不考虑进程内部状态 - 当然,如果你的进程正在与外部状态进行通信或调整,所有的赌注都会被关闭......
此外,您可以实施操作系统自身通常执行的解决方案:一个警告信号,要求进程尽可能清理(设置标志并优雅地退出可以优雅停止的内容),然后强制终止(如果进程)不会自行退出(这会阻止阻塞I / O等烦人的事情。)
应该构建所有服务,使得强制终止无害,因为这些进程是系统管理的,并且可能会被重启等事件终止 - 即,您的服务理想情况下应该允许无论如何腐败存储。
哦,还有一个最后的警告; Windows服务可以共享一个进程(我假设效率很高,虽然它让我觉得可以避免优化),所以如果你走这条路,你要确保你的服务不与其他人分享进程服务。您可以通过将选项SERVICE_WIN32_OWN_PROCESS传递给ChangeServiceConfig来确保这一点。