Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C] segnali si comportano in modo strano

    Salve ragazzi, sto facendo un programma che utilizzando i segnali deve gestire una gerarchia padre (P), figlio (F), nipote (N). Il padre si mette in attesa del figlio il quale ogni tot secondi stampa a video una stringa. Il nipote stampa anch'esso una stringa a video. Quando il processo figlio riceve una SIGINT dall'utente, deve uccidere il processo nipote (N) attraverso una SIGKILL e successivamente terminare e ritornare il suo stato al padre.
    Il mio problema è il seguente: quando uso la sigaction per gestire il segnale, al momento della kill, oltre ad uccidere il nipote (N) uccido anche il padre (P) e quindi il figlio viene adottato da init. La kill deve uccidere solo il nipote e non il padre!!! Che posso fare???
    Qui di seguito trovate il codice completo...Grazie a tutti per le risposte!!!

    codice:
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<signal.h>
    #include<errno.h>
    pid_t nipote;
    void catturaINT(int sig){
     printf("\nSegnale catturato\n");
     printf("Uccidero' %d\n",nipote);
     if(kill(nipote,SIGKILL)==0)
      printf("Kill eseguito con successo\n");
     else
      printf("Errore esecuzione kill %d\n",errno) ;
     exit(0);
    }
    int main(){
     pid_t pid;
     struct sigaction act;
     act.sa_handler=catturaINT;
     sigemptyset(&act.sa_mask);
     act.sa_flags=SA_RESETHAND;
     pid=fork(); /* genero un figlio */
     if (pid<0)
      printf("Errore nella creazione della fork()\n");
      else{
       if (pid==0){ 
       nipote=fork(); 
       /* il figlio genera a sua volta un figlio che sara' 
       * nipote del processo P */
       if(nipote<0)
        printf("Errore nella creazione della fork()\n");
       else{
        if(nipote==0){
         int i=0;
         while(1){
          printf("Sono il nipote di P figlio di F=%d e mi chiamo N=%d\n",getppid(),getpid());
          sleep(2);
         }
        }	
        else{
         sigaction(SIGINT,&act,0);
         while(1){
          printf("Sono F=%d e figlio di P=%d\n",getpid(),getppid());
          sleep(2);
         }
        }
       }
      }
      else{
       int stato;
       pid_t figlio=wait(&stato);
       if(WIFEXITED(stato))
        printf("Il figlio termina regolarmente con stato %d\n",WEXITSTATUS(stato));
       else
        printf("Terminazione anomala\n");
      }
     }
    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Sono ancora parecchio inesperto in fatto di programmazione in ambiene *nix (studio l'argomento da appena un paio di settimane, anche meno) ma non capisco una cosa

    La kill deve uccidere solo il nipote e non il padre!!! Che posso fare???
    ma la kill mica uccide anche il padre? Il padre termina con la chiamata a exit(0) alla fine dell' handler catturaINT o sbaglio? Mi sembra normale che termini anche il padre a quel punto...

    Scusa se non ho compreso il problema ^^
    every day above ground is a good one

  3. #3
    La kill uccide anche il padre!!! anche se si toglie la exit(0) nell'handler catturaINT, mandandolo in esecuzione il processo F avrà come padre il processo 1 alias il processo init

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Originariamente inviato da rictato
    La kill uccide anche il padre!!! anche se si toglie la exit(0) nell'handler catturaINT, mandandolo in esecuzione il processo F avrà come padre il processo 1 alias il processo init
    Guarda ti faccio vedere a me cosa succede.

    Se NON commento exit(0) alla fine di catturaINT (cioè in pratica se lascio il codice così come lo hai scritto), l'output è questo

    codice:
    YuYevon@slackware:~$ ./segnale
    Sono il nipote di P figlio di F=3893 e mi chiamo N=3894
    Sono F=3893 e figlio di P=3892
    Sono F=3893 e figlio di P=3892
    Sono il nipote di P figlio di F=3893 e mi chiamo N=3894
    Sono F=3893 e figlio di P=3892
    Sono il nipote di P figlio di F=3893 e mi chiamo N=3894
    
    #a questo punto invio il segnale SIGINT al processo 3893 da un'altra shell...
    
    Segnale catturato
    Uccidero' 3894
    Kill eseguito con successo
    Il figlio termina regolarmente con stato 0
    che mi sembra coerente con il programma che hai scritto, cioè ricevuto il segnale SIGINT il processo F ammazza suo figlio (N) e poi termina regolarmente con eixt(0). Il padre di F (P) riceve lo stato di terminazione 0 del figlio F (di cui attendeva la terminazione con wait()) e stampa "Il figlio termina regolarmente con stato 0"

    Se invece commento la exit(0), il processo F ammazzerà N una volta ricevuto il segnale SIGINT e però poi né lui né P vengono interrotti, e infatti la loro esecuzione continua (o per meglio dire continua F e P ne attende la terminazione)

    codice:
    YuYevon@slackware:~$ ./segnale
    Sono il nipote di P figlio di F=3983 e mi chiamo N=3984
    Sono F=3983 e figlio di P=3982
    Sono il nipote di P figlio di F=3983 e mi chiamo N=3984
    Sono F=3983 e figlio di P=3982
    Sono il nipote di P figlio di F=3983 e mi chiamo N=3984
    Sono F=3983 e figlio di P=3982
    Sono il nipote di P figlio di F=3983 e mi chiamo N=3984
    Sono F=3983 e figlio di P=3982
    
    #a questo punto invio il segnale SIGINT al processo 3983 da un'altra shell...
    
    Segnale catturato
    Uccidero' 3984
    Kill eseguito con successo
    Sono F=3983 e figlio di P=3982
    Sono F=3983 e figlio di P=3982
    Sono F=3983 e figlio di P=3982
    Sono F=3983 e figlio di P=3982
    every day above ground is a good one

  5. #5
    Sbagliavo io ad inviare il segnale!!! Grazie mille!!!
    Un'altra cosa sempre a riguardo: SIGINT non è il segnale inviato da terminale quando faccio CTRL+C???

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    In teoria sì, ctrl+c dovrebbe corrispondere a SIGINT, ctrl+z a SIGSTOP... eppure se provo a dare ctrl+c durante l'esecuzione del processo non succede niente... non saprei, bisognerebbe documentarsi un po'.
    every day above ground is a good one

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.