2015-05-13 13 views
7

Ich verwende Go, um ein paar Skripts zu starten, und wenn sie ein paar Probleme haben, benutzen sie das "Alarm" -Signal, ich weiß, Go kann diese Signale erfassen, aber ich muss die PID wissen, die den Ursprung hat Signal. in C auf das Signal-Handler wird eine Struktur geleitet, um die pid zu wissen, wer das Signal stammt, aber in Go sieht aus wie nicht der Fall istGo: Signalursprung

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) 
} 

das folgende Beispiel (aus dem Signal doc extrahiert) senden Sie mir das Signal, die ihren Ursprung der Anruf aber keine nützlichen Informationen (wie die PID)

Antwort

6

Nein, Sie können dies nicht in einer offiziell unterstützten Weise tun. Die Go-Runtime muss die Signalhandler besitzen und diese zusätzlichen Informationen werden in keiner Weise verfügbar gemacht.

Sie können dies immer noch von C aus tun, indem Sie einen neuen Signal-Handler einrichten, aber ich würde sehr vorsichtig damit umgehen (siehe Probleme wie issue/7227). Sie sind wahrscheinlich besser dran, eine andere Methode für die Kommunikation als ein Signal zu verwenden.

Hier ist ein Teil-Beispiel basierend auf Ians Code aus der Ausgabe 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) 
    } 
} 
+0

wie "explosiven" diese aproach ist? Ich meine, ich brauche nur die PID, um von einer Gorroutine gefangen zu werden, damit ich das Absenderkind töten kann, nichts Schickes. – Freaktor

+0

@Freaktor: Es sperrt dich in die Notwendigkeit von Cgo und Linux, es kann irgendwann brechen, und es ist wahrscheinlich für etwas, wo es wahrscheinlich einen besseren Weg gibt. Vielleicht, wenn du besser beschreibst, was das "Alarmsignal" ist und warum das Go-Programm derjenige sein muss, um das Kind zu töten. – JimB

+0

Ich rufe einige Nagios-Plugins an und verwende im Moment ein Timeout über die Ausführung, aber der Nagios-Standard sagt, dass die Plugins das Alarmsignal aussenden werden, wenn sie ein Problem haben, also versuche ich dieses Ereignis einzufangen. – Freaktor