Domanda SystemCall C

Stato
Discussione chiusa ad ulteriori risposte.

N0body

Utente Bronze
15 Novembre 2016
17
5
1
35
Ultima modifica da un moderatore:
Buona sera,ho un problema sulle system call di Unix.
Vorrei creare un figlio che esegue fibonacci ricorsivo,e al segnale di interruzione (CTRL+C),mi esegua la funzione che gestisco io. Nella funzione chiede se vuole terminare e di conseguenza uccido il figlio e il padre tramite una kill,o se continuare e quindi continuo il fibonacci.
Il problema nasce quando inizia il fibonacci,essendo due processo concorrenti mi aspetto che al mio CTRL+C il ciclo si fermi e il sistema operativo mi faccia gestire l'interruzione,ma questo non accade il segnale viene ignorato e il ciclo continua a stampare il fibonacci. Lasco il codice tra spoiler.
Grazie a tutti per la disponibilità e il tempo dedicatomi.
C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>

int fib (int n){
    if(n<=1) return (n);
    else return (fib(n-1)+fib(n-2));
}

void cntrl_c_handler(int sig){
    int pid;
    pid=fork();
    char answer[512];
    printf("Segnale di interruzione\n");
    if(pid <0){
        printf("Errore fork\n");
        exit(0);}
    else if(pid == 0){
    printf("Ricevuto errore,sig =%d vuoi continuare o uscire?\n",sig);
    scanf("%s",answer);}
    if(*answer == 'c') exit(0);
    else{ 
    kill(getppid(),SIGKILL);//figlio uccide il padre
    raise(SIGKILL);//suicidio
    }
}
main(){
int f=fork();
    if(f <0 ){
        printf("Errore fork\n");
        exit(-1);}
    else if(f == 0){
        for(int i=0;i<60;i++){
        printf("fib(%d)=%2d\n",i,fib(i));
        if(signal(SIGINT,cntrl_c_handler)==SIG_ERR)
            printf("Can't catch SIGINT\n");
        }
    }else if(f>0){
        printf("Sono il padre\n");
        printf("Pid di mio figlio %d\n",f);
        printf("Bye\n");
        exit(0);}
}
 
Ho fatto un po' di pulizia per far funzionare il tutto: alcune cose erano veramente senza senso (la signal dentro un for?) e altre erano sbagliate concettualmente. Dai un'occhiata:
C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

int fib (int n) {
    if (n <= 1) return n;
    else return fib(n-1) + fib(n-2);
}

void cntrl_c_handler(int sig) {
    char answer[512];

    printf("Segnale di interruzione\n");
    printf("sig = %d, vuoi continuare o uscire?\n",sig);
    scanf("%s", answer);

    if(answer[0] == 'c') // c = close
        exit(0); // il figlio termina correttamente, il padre si sveglia
}

int main()
{
    int f = fork();

    if(f < 0) {
        printf("Errore fork\n");
        exit(-1);
    }

    if(f == 0) {
        // nel figlio, gestisco SIGINT con cntrl_c_handler
        if(signal(SIGINT,cntrl_c_handler) == SIG_ERR)
            printf("Can't catch SIGINT\n");

        for(int i=0;i<60;i++) {
            printf("fib(%d)=%2d\n", i, fib(i));
        }
    }
    else {
        // nel padre, ignoro SIGINT
        if(signal(SIGINT, SIG_IGN) == SIG_ERR)
            printf("Can't catch SIGINT\n");

        printf("Sono il padre\n");
        printf("Pid di mio figlio %d\n",f);
        wait(NULL); // prima di morire, aspetto il figlio
        printf("Bye\n");
    }

    return 0;
}

Il codice è talmente semplice che secondo me basta vederlo per capire perché funziona e paragonarlo con il tuo per vedere gli errori, ma se hai qualsiasi tipo di domanda non farti problemi a farla.
 
  • Mi piace
Reazioni: Kolo93
Grazie per aver visto,e corretto il codice. Apprezzo molto il tempo che hai speso nel tutto e la disponibilità del precedente topic e dell'attuale.
Comunque cose senza senso ne avrò scritte molte anche in altri programmi sempre sulle system call,essendo alle prime armi su questo argomento mi riesce facile.
Il codice è effettivamente semplice e leggibile a occhio,tuttavia proverò ad aggiungere la kill nella funzione handler per provare anche quel tipo di segnale.
 
Stato
Discussione chiusa ad ulteriori risposte.