繁体   English   中英

最干净的方法来停止Win32上的进程?

[英]Cleanest way to stop a process on Win32?

在用C ++实现应用服务器及其客户端库时,我很难找到一种干净可靠的方法来在Windows服务器关闭时停止客户端进程。

假设服务器及其客户端在同一用户下运行,则要求是:

  • 该解决方案应在以下情况下工作:
    • 客户端可能各自具有控制台或GUI。
    • 用户可能没有特权。
    • 客户端可能变得无响应(无限循环,死锁)。
    • 客户端可以是(也可以不是)服务器的子级(直接或间接)。
  • 除非受到客户端缺陷的阻止,否则应允许客户端有机会干净地退出(释放其资源,将一些数据同步到磁盘...),并有一些合理的时间这样做。
  • 在关闭过程中,应将所有客户端返回代码提供给服务器(如果可能)。
  • 服务器应等待所有客户端消失。

在进行此编辑时,以下大多数答案都主张在服务器及其客户端之间使用共享内存(或其他IPC机制)来传达关闭命令和客户端状态。 这些解决方案可以使用,但是需要客户端成功初始化库。

我没有说的是,服务器还用于启动客户端,在某些情况下还用于根本不使用客户端库的其他程序/脚本。 一个不依赖服务器与客户端之间正常通信的解决方案会更好(如果可能)。

前一段时间,我偶然发现了一个C代码片段(在我相信的MSDN中),该代码片段执行以下操作:

  1. 在关闭过程中通过CreateRemoteThread启动线程。
  2. 让该线程直接调用ExitProcess。

不幸的是,现在我正在寻找它,我找不到它,并且搜索结果似乎暗示此技巧在Vista上不再起作用。 有什么专家意见吗?

如果使用线程,一个简单的解决方案是使用命名的系统事件,线程在事件上休眠以等待被信号通知,控制应用程序可以在希望客户端应用程序退出时向事件发送信号。

对于UI应用程序,它(线程)可以将消息发布到主窗口中,WM_ CLOSE或QUIT我忘记了,在控制台应用程序中它可以发出CTRL-C,或者如果主控制台代码循环了,它可以检查某些退出条件由线程设置。

无论哪种方式,都不要使用指示客户端退出的客户端应用程序,而是使用OS发出信号指示退出。 如果睡眠线程使用WaitForSingleObject进行睡眠,则实际上将不占用任何CPU资源。

使用PostMessage或命名事件。

回复:PostMessage-GUI以外的应用程序以及GUI线程以外的线程都可以具有消息循环,这对于诸如此类的事情非常有用。 (实际上,COM在幕后使用了消息循环。)我之前使用ATL做到过,但是对此有些生锈。

如果要对来自“不良”进程的恶意攻击保持鲁棒性,请包括客户端/服务器共享的私钥作为消息中的参数之一。

命名事件方法可能更简单; 使用名称为客户端/服务器共享的机密名称的CreateEvent,并让相应的应用在其主循环内检查事件的状态(例如,超时为0的WaitForSingleObject),以确定是否关闭。

您需要客户端和服务器之间的某种IPC。 如果所有客户都是孩子,我认为管道将是最简单的。 因为它们不是,所以我猜可以使用服务器操作的共享内存段来注册客户端,发出shutdown命令以及收集成功关闭客户端发布的返回代码。

客户端在此共享内存区域中放置其进程ID,以便服务器可以使用TerminateProcess()强制终止任何无响应的客户端(对服务器进行模数化)。

如果您愿意使用IPC路由,请使客户端和服务器之间的正常通信双向进行,以使服务器要求客户端关闭。 否则,请客户进行投票。 或作为最后的手段,当向服务器发出请求时,应指示客户端退出。 您可以让库用户注册退出回调,但是据我所知,最好的方法是在告知客户端关闭时,在客户端库中简单地调用“ exit”。 如果客户端陷入关闭代码中,则服务器需要能够通过忽略该客户端的数据结构和连接来解决该问题。

这是一个非常普遍的问题,并且存在一些不一致之处。

尽管这不是100%的规则,但大多数控制台应用程序都可以运行完成,而GUI应用程序可以运行直到用户终止它们为止(服务一直运行到通过SCM停止)。 因此,请求关闭GUI更容易。 您发送给他们等效的Alt-F4。 但是对于控制台程序,您必须向他们发送等效于Ctrl-C的控件,并希望他们能够处理它。 在这两种情况下,您只需等待。 如果该过程仍然存在,则可以将其击落(TerminateProcess),并祈祷损害受到限制。 但是您的HDD可以填充临时文件。

GUI应用程序通常没有退出代码-它们会去哪里? 并且被定义强行终止的控制台进程不会退出,因此它没有退出代码。 因此,在服务器关闭的情况下,不要期望退出代码。

如果连接了调试器,通常无法从另一个应用程序中关闭该进程。 这将使调试器无法调试退出代码!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM