一尘不染

转到:获取信号来源

go

我正在使用Go启动一些脚本,当它们遇到问题时,它们会使用“警报”信号,我知道Go可以捕获这些信号,但我需要知道产生该信号的PID。在C中向信号处理程序传递一个结构以了解发出信号的pid,但在Go中看起来并非如此

package main

import (
    "fmt"
    "os"
    "os/signal"
)

func main() {

    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt, os.Kill)

    s := <-c
    fmt.Println("Got signal:", s)
    fmt.Printf("%+v\n",s)
}

下面的示例(从信号文档中提取)向我发送了发起呼叫的信号,但没有任何有用的信息(例如pid)


阅读 230

收藏
2020-07-02

共1个答案

一尘不染

不,您不能以官方支持的方式执行此操作。Go运行时需要拥有信号处理程序,并且不会以任何方式公开额外的信息。

通过设置新的信号处理程序,您仍然可以从C中做到这一点,但是我对此会非常谨慎(请参阅诸如issue /
7227之
类的问题)。您最好使用信号以外的其他通信方法。

这是一个基于Ian从问题7227开始的代码的部分示例:

package main

/*
#include <stdio.h>
#include <signal.h>
#include <string.h>

struct sigaction old_action;
void handler(int signum, siginfo_t *info, void *context) {
    printf("Sent by %d\n", info->si_pid);
}

void test() {
    struct sigaction action;
    sigaction(SIGUSR1, NULL, &action);
    memset(&action, 0, sizeof action);
    sigfillset(&action.sa_mask);
    action.sa_sigaction = handler;
    action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO | SA_ONSTACK;
    sigaction(SIGUSR1, &action, &old_action);
}
*/
import "C"

import (
    "os"
    "syscall"
    "time"
)

func main() {
    C.test()
    pid := os.Getpid()
    for {
        syscall.Kill(pid, syscall.SIGUSR1)
        time.Sleep(time.Second)
    }
}
2020-07-02