Per quanto riguarda i processi in background utilizzando fork () e processi figli nel mio guscio manichino

StackOverflow https://stackoverflow.com/questions/8319484

  •  25-10-2019
  •  | 
  •  

Domanda

Sto cercando di creare un semplice programma di shell in C. Cosa ho bisogno di fare è fornire all'utente un prompt in cui si possono eseguire altri programmi locali. Posso fare quella parte bene, con una forchetta (), in cui le attese di processo genitore () sul bambino, e il bambino execvp () 's del programma.

Tuttavia, se il carattere '&' viene aggiunto alla fine del comando dell'utente, ho bisogno del loro programma da eseguire in background, il che significa che ho bisogno del genitore di non aspettare il processo figlio, ma invece immediatamente tornare la richiesta di l'utente, consentendo nel contempo il processo in background di continuare a correre, ma non permettendo così di visualizzare nulla sullo schermo. Voglio solo essere in grado di verificare che ancora esiste con il comando ps.

ho cercato di capire l'idea alla base utilizzando fork () per creare un bambino, poi la forcella bambino () di nuovo per creare un nipote di sorta, poi subito exit () - ing il processo figlio. cioè, orfano il nipote. Presumibilmente questo permette al genitore di attendere ancora sul bambino, ma dal momento che il bambino finisce efficacemente quasi subito, è come se non aspetta affatto? Qualcosa su di zombie follia? Non lo so. Diversi siti ho incontrato sembrano raccomandare questo come un modo per eseguire un processo in background.

Tuttavia, quando provo a fare questo, ho cose selvagge che avvengono con il flusso del programma, il processo di 'background' continua a visualizzare in ingresso sullo schermo, e io non sono davvero sicuro dove andare da qui.

Questa è la mia implementazione del codice, che sono sicuro che è del tutto sbagliato. Mi chiedo solo se tutta questa faccenda nipotino è anche la necessità che strada prendere, e se sì, cosa c'è di sbagliato con il mio codice?

36 int main(int argc, char *argv[])
37 {
38     char buffer[512];
39     char *args[16];
40     int background;
41     int *status;
42     size_t arg_ct;
43     pid_t pid;
44 
45     while(1)
46     {
47         printf("> ");
48         fgets(buffer, 512, stdin);
49         parse_args(buffer, args, 16, &arg_ct);
50 
51         if (arg_ct == 0) continue;
52 
53         if (!strcmp(args[0], "exit"))
54         {
55             exit(0);
56         }
57 
58         pid = fork();  //here I fork and create a child process
61 
62         if (pid && !background)  //i.e. if it's the parent process and don't need to run in the background (this is the part that seems to work)
63         {
64             printf("Waiting on child (%d).\n", pid);
65             pid = wait(status);
66             printf("Child (%d) finished.\n", pid);
67         }
68         else
69         {
70             if (background && pid == 0) { //if it's a child process and i need to run the command in background
71                
72                 pid = fork(); //fork child and create a grandchild
73                 if (pid) exit(0); //exit child and orphan grandchild
74                 
75                 execvp(args[0], args); //orphan execs the command then exits
76                 exit(1);
77 
78             } else exit(0);
79         }
80     }
81     return 0;
82 }

P.S. Per essere chiari, mi serve il processo che sto correndo in background per non fare di nuovo un suono, anche se è ottenuto un ciclo infinito di dichiarazioni di stampa o qualcosa del genere. Voglio solo fare in modo che è ancora in esecuzione in background tramite ps -a o qualcosa del genere.

Ci scusiamo per la confusione spiegazione io non so come spiegarlo meglio.

Grazie in anticipo

P.P.S sarò sua attuazione in modo che ogni successivo comando determinerà il valore booleano di 'background', mi dispiace per la confusione

È stato utile?

Soluzione

Non si desidera utilizzare il metodo della partita doppia fork() in un guscio -. Che è per la scrittura di demoni che specificamente vogliono fuggire dal controllo da parte guscio che li ha

Al contrario, il modo di riprodurre il comportamento di & in gusci esistenti è quello di chiamare fork(), poi nel setpgid(0, 0); chiamata bambino a mettere il bambino in un nuovo gruppo di processi . Il genitore continua solo sul (forse dopo aver stampato la PID del bambino) -. Non chiama wait()

Ogni terminale può avere un solo gruppo di processo in primo piano, che è il gruppo processo che è attualmente consentito per inviare l'output al terminale. Questo rimarrà il gruppo di processi di cui la vostra shell è un membro, in modo che il guscio rimarrà in primo piano.

Se un gruppo di processo in background tenta di leggere dal terminale, verrà inviato un segnale per fermarlo. Uscita al terminale è ancora consentito - questo è normale (prova ls & nella shell regolare). Per implementare il comando fg nella shell, è necessario la funzione tcsetpgrp() di cambiare il gruppo di processi in primo piano.

Si vuole anche chiamare waitpid() con l'opzione WNOHANG Regolare - L'esempio, subito prima di visualizzare prompt di shell. Questo vi permetterà di rilevare quando il processo in background è terminato o interrotto (o, in alternativa, è possibile gestire il segnale SIGCHLD).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top