2015-05-13 16 views
7

Sto usando Vai per lanciare un paio di script e quando hanno alcuni problemi usano il segnale di "avviso", so che Go può catturare quei segnali ma ho bisogno di conoscere il PID che ha originato il Segnale. in C al gestore di segnale viene passato una struttura di conoscere il pid che ha originato il segnale, ma in Go sembra non è il casoVai: Ottieni l'origine del segnale

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

l'esempio di seguito (estratta dal doc segnale) mi inviare il segnale che ha dato origine la chiamata ma non tutte le informazioni utili (come il pid)

risposta

6

No, non è possibile farlo in modo ufficialmente supportato. Il runtime Go deve possedere i gestori di segnale e tali informazioni aggiuntive non sono esposte in alcun modo.

Si può ancora essere in grado di farlo da C impostando un nuovo gestore di segnale, ma sarei molto cauto nel fare ciò (vedere problemi come issue/7227). Probabilmente stai meglio usando un altro metodo di comunicazione diverso da un segnale.

Ecco un esempio parziale basato sul codice di Ian dal numero 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

come "esplosivo" questo aproach è? Voglio dire, ho solo bisogno del pid per essere catturato da una goroutine così posso uccidere il bambino mittente, niente di strano. – Freaktor

+0

@Freaktor: Ti blocca a richiedere cgo e linux, potrebbe rompersi ad un certo punto, ed è probabile che ci sia qualcosa in cui probabilmente c'è un modo migliore. Forse se dovessi descrivere meglio qual è il segnale di "avviso" e perché il programma di go deve essere quello per uccidere il bambino. – JimB

+0

ho chiamato alcuni plugin nagios e attualmente sto usando un timeout sull'esecuzione, ma lo standard nagios dice che i plug-in emetteranno il segnale di allarme se hanno qualche problema, quindi sto cercando di catturare quell'evento. – Freaktor