【问题标题】:How to terminate another application using c++/c#/vc++ gracefully?如何优雅地使用 c++/c#/vc++ 终止另一个应用程序?
【发布时间】:2018-10-02 16:06:33
【问题描述】:

我有一个运行无限循环并在该循环中执行一些重要功能的应用程序。我需要为用户提供另一个应用程序,它将以无限循环终止应用程序。问题是如果用户在应用程序处于循环内部执行某些操作时终止应用程序会怎样。这将导致不一致的状态。我尝试了 kill() 和 TerminateProcess 但它们没有帮助。有什么办法可以用无限循环向应用程序发出信号,完成你的迭代并退出?我对 c#、cpp 和 vc++ 中的解决方案持开放态度。

编辑:

循环程序的源代码是可访问的。

【问题讨论】:

  • 不需要额外的应用程序来做到这一点。
  • 我要求有一个额外的应用程序来做到这一点。无限循环应用程序将在后台运行,并应在用户需要时停止。为什么你们这么快就下结论了??
  • 没有明确的细节是不可能回答你的问题的。根据您的评论,请考虑在后台进程中侦听端口。
  • 如果不改变循环程序,答案是否定的。如果您可以更改循环程序,请更新问题。
  • 有很多方法可以做到这一点,通用术语是进程间通信。可能的方法是: 使用文件的存在作为标志;共享内存;插座;跨进程信号量/互斥体(不是 C++ std::mutex)...等。在一个进程中设置标志;测试,如果设置清除它并在另一个中执行您的操作。

标签: c# c++ windows visual-c++ process


【解决方案1】:

虽然进程间通信有很多变体,但为此目的,一个简单的事件就足够了。

过程中你需要控制:

  • hEvent = CreateEvent()(有名字,让它足够独特)
  • 定期使用WaitForSingleObject(hEvent, ZERO_TIMEOUT) 进行检查

从流程做控制:

  • hEvent = OpenEvent() 传递同名
  • SetEvent(hEvent) 会导致其他进程中WaitForSingleObject 的返回值发生变化。

更好的方法可能是在主应用程序中启动一个后台线程,该线程创建一个窗口和一个任务栏图标,菜单上有一个退出选项。那么你只需要在线程之间共享一个事件,而不是在进程之间共享一个事件,这样就不需要唯一的名称了。

【讨论】:

  • 使用窗口的另一个好处是,您的进程可以在通过 taskkill.exe 终止时正常退出。只需处理WM_CLOSE 消息。令人讨厌的是,GUI 任务管理器中的“结束任务”仅在窗口可见时才会这样工作。否则它会强制终止进程。
【解决方案2】:

一个运行无限循环并执行一些重要功能的应用程序

只要它执行“重要功能”,相关程序就有办法从某个地方(例如,从文件或网络套接字)获取新的输入数据。因此,您可以在输入数据中添加一个具有“操作结束”含义的特殊标记。收到此类令牌后,程序将知道是时候自行关闭了。这种性质的最简单标记之一是常规文件的文件结尾或远程端套接字关闭。

我刚才描述的方法很简单,可以称为“带内控制通道”。也就是说,您使用单个通道来提供要处理的数据和要控制的命令(即使只有一个命令,“停止”)。

替代方案是“带外控制通道”,即在应用程序之间传递命令的第二个通道。

问题是如果用户在应用程序处于循环内部执行某些操作时终止应用程序会怎样。这将导致不一致的状态。

您尝试使用kill 是使用称为进程间signals 的工具的一种可能性。要正确使用它,接收程序必须注册一个信号处理程序例程以自行启动关闭。发送方应使用匹配的信号编号。使用kill(POSIX 中的SIGKILL)不是最佳选择,因为它具有特殊的行为并且不能使用自定义信号处理程序分配。在 POSIX 中,最好使用 SIGUSR1 或许多其他信号之一。我不记得本机 Windows 等效项。

在传统操作系统中,有多种机制可以组织进程之间的处理器间通信,请参阅Wikipedia 以获取从共享文件到命名管道和网络套接字的所有内容的完整列表。选择最适合您需求的一种。你只需要传递一个数据位,所以基本上最容易编程的就是最好的。

【讨论】:

  • 在 Windows 中,任务管理器和 taskkill.exe 通过将WM_CLOSE 发布到其窗口来优雅地结束任务。任务管理器只使用可见窗口,但 taskkill.exe 也适用于不可见窗口。后台任务也可以实现为服务,可以通过 net.exe 或 sc.exe 从命令行控制,也可以使用系统管理控制台的 services.msc 管理单元进行控制。
猜你喜欢
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 2021-05-28
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多