【问题标题】:Start process and terminate at later stage启动进程并在后期终止
【发布时间】:2016-08-01 05:37:02
【问题描述】:

我正在用 Go 编写一个 SDK,集成商将通过本地套接字连接与之通信。

从集成应用程序中,我需要一种将 SDK 作为进程启动的方法,但更重要的是,我需要能够在主应用程序关闭时取消该进程。

这个问题与语言无关(我认为),因为我认为挑战与 linux 相关。即如何启动程序并在以后取消它。

一些可能的方法:

  • 我认为这是通过 exec 启动程序,获取它的 PID 或某个 ID,然后使用它在以后杀死的情况。可能需要 Sudo 来执行此操作,这并不理想。此外,这也不是好的做法,因为您将有效地强制关闭 SDK,没有时间进行清理。
  • 通过任何方式启动程序。一旦准备好关闭,只需通过 SDK API 发送一个“关闭”命令,这将允许 SDK 清理、管理状态然后退出应用程序。

请问这方面的最佳做法是什么?

【问题讨论】:

  • 1) 为什么要使用sudo 来终止您创建的进程?它应该与调用程序具有相同的权限。 2) 你有什么理由排除signals 先验?
  • 1) 我不确定您是否需要 sudo 来杀死一般进程。 2)我不知道信号..请详细说明..
  • 1) 据我所知,没有 2) 给定一个信号,您可以为它设置一个信号处理程序,这是一个每当信号通过异步传递到进程时触发的函数打断。因此,您可以将特定信号发送到您的应用程序,并定义一个信号处理程序,通过适当地释放其资源来优雅地终止它。具体细节可能取决于您使用的技术(进程、posix 线程等)。你可以在这里找到更多相关信息 -> man7.org/linux/man-pages/man7/signal.7.html

标签: linux ipc rpc


【解决方案1】:

假设您使用的是 Linux 或类似的 Unix:

你在正确的轨道上。你不需要sudo。到目前为止,cmets 都指向正确的方向,但没有详细说明。

有关此处提到的功能的详细信息,请参阅手册页 (man 2 ...) 的第 2 部分。它们被记录为从 C 调用。我没有使用 Go 的经验来帮助确定如何在那里使用它们。

集成器应用程序将被称为“父”进程。 SDK-as-a-process 将被称为“子”进程。一个进程通过调用 fork() 创建一个子进程并成为它的父进程。新进程是父进程的副本,运行相同的代码,并且大部分情况下都具有相同的状态(内存中的数据)。但是 fork() 向父子和子返回不同的值,因此每个都可以确定其在关系中的角色。这包括将子进程标识符 (pid) 通知父进程。坚持这个价值观。然后,孩子使用 exec() 在现有进程中执行不同的程序,即您的 SDK 二进制文件。 fork-then-exec 的替代方法是 posix_spawn(),它包含相当多的参数(但如果需要,可以提供更大的控制权)。

将子进程设计为响应信号而不是通过 API 发出的命令而关闭,这将允许父进程以外的进程以标准方式启动干净关闭。例如,这可能对管理员或用户有用;它允许从 shell 命令行或脚本发送关闭信号。

子进程安装一个信号处理函数,当子进程接收到信号时将调用该函数,方法是调用 signal()(或更复杂的 sigaction(),因为它的可移植性而被推荐)。有不同的信号可以被发送/接收,由不同的整数值标识(以及像 SIGTERM 这样的名称)。您在调用 signal() 时表明您有兴趣接收哪个。当您的信号处理函数被调用时,您已收到信号,并且可以启动干净关闭。

当父母希望孩子彻底关闭时,父母会使用不幸命名的 kill() 向孩子发送信号。不幸的是,因为信号可以用于其他目的而命名。无论如何,您将 pid(由 fork() 返回)和您要发送的特定信号(例如 SIGTERM)传递给 kill()。

父母还可以通过调用waitpid()来确定孩子何时完全关闭,再次传递fork()返回的pid;或者通过注册接收信号 SIGCHLD。注册以接收 SIGCHLD fork()/exec() 之前,否则您可能会错过信号。

实际上,在收到 SIGCHLD 之后调用 waitpid() 是很重要的,以便释放持有子进程退出状态的资源,以便操作系统可以清理进程的最后残余。不这样做会使孩子成为一个“僵尸”过程,无法完全回收。僵尸过多,操作系统将无法启动新进程。

如果进程拒绝干净地关闭或拒绝按照您的要求快速关闭,您可以通过发送信号 SIGKILL 强制它退出(不执行其清理代码)。

exec()、waitpid() 和 posix_spawn() 的变体有不同的名称和行为,在它们的手册页中有所提及。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多