signal



  • Hi Leute
    ich hab nen riesen Problem. Ich hab mit fork() einen childprozess erzeugt.
    Der vater setzt mit signal() einen handler für SIGALRM ->signal(SIGALRM, meldung)
    wobei der handler so aussieht:

    void meldung(int s)
    {
    fprintf(stdout,"\nDies ist ein SigHandler");
    return;
    }

    nun übergebe ich die pid des vaterprozeses über ne pipe an das child
    (Dies funktioniert, habe es getestet);

    und sende aus dem child ein SIGALRM 'kill(vater_pid, SIGALRM)'
    die meldung (aus dem Vaterprozess) erscheint nicht, was mache ich falsch??

    hier der code:
    [cpp]
    #include <stdio.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>

    int main(void)
    {

    int pipe_fd[2];
    pid_t pid;

    if(pipe(pipe_fd)== -1){
    perror("\npipe() failed!\n");
    exit(1);
    }

    if(!(pid=fork())){ /* Kindprozess */
    pid_t vater_pid;

    close(pipe_fd[1]); /*Schreibhandle schließen */
    read(pipe_fd[0], &vater_pid, sizeof(pid_t));
    close(pipe_fd[0]); /*Lesehandle schließen */
    kill(vater_pid,SIGALRM); /* Signal an Vater senden /
    }
    else{ /
    Vaterprozess */
    void meldung(int s)
    { /* Sighandler */
    fprintf(stdout,"\nSignal erhalten!\n");
    return;
    }
    /* Sighandler setzen /
    if(signal(SIGALRM,meldung)==SIG_ERR){
    perror("\nsignal() failed!");
    exit(1);
    }
    close(pipe_fd[0]); /
    Lesehandle schließen /
    write(pipe_fd[1], &pid, sizeof(pid_t));
    close(pipe_fd[1]); /
    Schreibhandle schließen */
    wait();
    }
    return(1);
    }



  • Die pid, die fork() zurückgibt ist die pid des Kindes nicht des Vaters. Du schickst also dem Kind seine eigene Pid.

    Hier mal ein Code der funktionieren sollte:

    #include <stdio.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    void meldung(int s)
    {
       fprintf(stdout,"\nSignal erhalten! Pid: %d\n", getpid());
    }
    
    int main(void)
    {
       pid_t pid;
       struct sigaction alarm_action;
       alarm_action.sa_handler = meldung;
       sigemptyset(&alarm_action.sa_mask);
       alarm_action.sa_flags = 0;
    
       if (sigaction(SIGALRM, &alarm_action, 0) == -1)
       {
          perror("\nsignal() failed!");
          exit(1);
       }
    
       if(!(pid=fork()))
       {
          if (pid == -1)
          {
             perror("Fork failed!");
             exit(1);
          }
          fprintf(stdout, "Child pid: %d\n", getpid());
          kill(getppid(),SIGALRM);
       }
       else
       {
          fprintf(stdout, "Parent pid: %d\n", getpid());
          wait();
       }
    
       return 0;
    }
    

    Ich hab mal auch die Funktion signal durch sigaction ersetzt.



  • Vielen dank für deine Antwort! 🙂

    Die Tatsachen die Du geliefert hast kannte ich tatsächlich noch nicht.
    (Tja, ich lern erst 🙂 ).
    Die Funktionen kannte ich bis dahin noch nicht:
    getppid() getpid()

    Doch eine Frage habe ich noch überal sehe ich die funktion sigaction()
    sowie die dazugehörige structur(alles sehr kriptisch) doch nirgends ne
    erklärung. Kannst Du mir weiterhelfen?

    thx



  • signal() ist nicht besonders zuverlässig. sigaction() bietet sogenannte "reliable signals". Warum man lieber sigaction anstatt signal verwenden möchte bietet jede gute Einführung zu Signals. Zumindest in "APUE" und "Linux Unix Systemprogrammierung" sollte dies ausführlich erklärt werden.


Anmelden zum Antworten