【问题标题】:.net-core app: how to send SIGTERM to child processes?.net-core 应用程序:如何向子进程发送 SIGTERM?
【发布时间】:2016-12-08 14:23:00
【问题描述】:

在 Linux 上运行的 .net-core 应用程序是否可以向子进程发送 SIGTERM 信号?

我们正在考虑将我们的 .net 应用程序移植到 .net-core 并在 Linux 上运行它,以避免当前的信号实现(即从父进程发送 CloseMainWindow(),并使用 pywin32 包,在子进程中使用 SetConsoleCtrlHandler()进程)

【问题讨论】:

  • 如果您的问题尚未得到完全解答,请考虑 accepting 提供答案或提供反馈。

标签: signals .net-core


【解决方案1】:

https://github.com/mono/mono/blob/master/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs 中的实现的启发,这里有一个实用程序类,可以做你想做的事情

public static class ProcessUtils
{        
    [DllImport ("libc", SetLastError=true, EntryPoint="kill")]
    private static extern int sys_kill (int pid, int sig);
    
    public static void Kill(this Process process, Signum sig)
    {
        sys_kill(process.Id, (int) sig);
    }
}

public enum Signum : int {
    SIGHUP    =  1, // Hangup (POSIX).
    SIGINT    =  2, // Interrupt (ANSI).
    SIGQUIT   =  3, // Quit (POSIX).
    SIGILL    =  4, // Illegal instruction (ANSI).
    SIGTRAP   =  5, // Trace trap (POSIX).
    SIGABRT   =  6, // Abort (ANSI).
    SIGIOT    =  6, // IOT trap (4.2 BSD).
    SIGBUS    =  7, // BUS error (4.2 BSD).
    SIGFPE    =  8, // Floating-point exception (ANSI).
    SIGKILL   =  9, // Kill, unblockable (POSIX).
    SIGUSR1   = 10, // User-defined signal 1 (POSIX).
    SIGSEGV   = 11, // Segmentation violation (ANSI).
    SIGUSR2   = 12, // User-defined signal 2 (POSIX).
    SIGPIPE   = 13, // Broken pipe (POSIX).
    SIGALRM   = 14, // Alarm clock (POSIX).
    SIGTERM   = 15, // Termination (ANSI).
    SIGSTKFLT = 16, // Stack fault.
    SIGCLD    = SIGCHLD, // Same as SIGCHLD (System V).
    SIGCHLD   = 17, // Child status has changed (POSIX).
    SIGCONT   = 18, // Continue (POSIX).
    SIGSTOP   = 19, // Stop, unblockable (POSIX).
    SIGTSTP   = 20, // Keyboard stop (POSIX).
    SIGTTIN   = 21, // Background read from tty (POSIX).
    SIGTTOU   = 22, // Background write to tty (POSIX).
    SIGURG    = 23, // Urgent condition on socket (4.2 BSD).
    SIGXCPU   = 24, // CPU limit exceeded (4.2 BSD).
    SIGXFSZ   = 25, // File size limit exceeded (4.2 BSD).
    SIGVTALRM = 26, // Virtual alarm clock (4.2 BSD).
    SIGPROF   = 27, // Profiling alarm clock (4.2 BSD).
    SIGWINCH  = 28, // Window size change (4.3 BSD, Sun).
    SIGPOLL   = SIGIO, // Pollable event occurred (System V).
    SIGIO     = 29, // I/O now possible (4.2 BSD).
    SIGPWR    = 30, // Power failure restart (System V).
    SIGSYS    = 31, // Bad system call.
    SIGUNUSED = 31
}

【讨论】:

  • 怎么样:public static void Kill(Signum sig, params System.Diagnostics.Process[] processes) ?然后您可以将 System.Diagnostics.Process.GetProcessesByName("nginx") 传递给该方法,如果您只给它一个进程,它也可以工作。
  • @StefanSteiger 当然,如果您的用例是一次杀死多个进程,它也可以工作。
【解决方案2】:

答案似乎是否定的,不幸的是(而且令人惊讶)。

我的研究:

可以通过调用 Process.Kill 来停止进程。在 Linux 上,这是 通过发送 SIGKILL 信号来实现,该信号告诉内核 立即终止应用程序。无法发送 SIGTERM 信号,它请求应用程序优雅地 终止。

来源:https://developers.redhat.com/blog/2019/10/29/the-net-process-class-on-linux/

此外,这似乎已经讨论过,但已被丢弃为“不必要的”:

关闭上面直接显示的现有专用 API @tmds 用于一般信号发送和处理 https://www.nuget.org/packages/Mono.Posix.NETStandard/

Mono.Posix.NETStandard 似乎不允许发送信号以由进程 ID 处理:

Mono.Posix 不允许您向进程发送信号,因为它 进程标识。因此,对于此目的,它是毫无用处的 问题。

来源:https://github.com/dotnet/corefx/issues/3188

如果有人对 OP 的问题有一个可行的解决方案,我也有兴趣知道如何去做,如果可能的话。

【讨论】:

    猜你喜欢
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多