In Bezug auf Hintergrundprozesse unter Verwendung von Fork () und untergeordneten Prozessen in meiner Dummy -Shell

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

  •  25-10-2019
  •  | 
  •  

Frage

Ich versuche, ein einfaches Shell -Programm in C zu erstellen. Ich muss dem Benutzer eine Eingabeaufforderung zur Verfügung stellen, in der er andere lokale Programme ausführen kann. Ich kann diesen Teil gut machen, indem ich eine gabel () verwendete, in der der übergeordnete Prozess () auf das Kind wartet, und das Programm Child EXECVP () das Programm.

Wenn der Charakter '&' jedoch am Ende des Benutzers angehängt ist, muss ihr Programm im Hintergrund ausgeführt werden, was bedeutet, dass der Elternteil nicht auf den untergeordneten Prozess wartet, sondern die Eingabeaufforderung sofort an den Benutzer zurückgibt. während der Hintergrundprozess weiter ausgeführt wird, aber nicht zulassen, dass er etwas auf dem Bildschirm anzeigt. Ich möchte nur überprüfen, ob es immer noch über PS -Befehl existiert.

Ich habe versucht, die Idee hinter der Verwendung von Fork () zu verstehen, um ein Kind zu erstellen, und dann das Kind Fork () erneut zu haben, um ein Enkelkind zu erstellen, und dann sofort das Kind beenden (). dh Orphan das Enkelkind. Angeblich ermöglicht dies dem Elternteil, immer noch auf das Kind zu warten, aber da das Kind fast sofort endet, ist es so, als ob es überhaupt nicht wartet? Etwas über Zombie -Wahnsinn? Ich weiß nicht. Mehrere Websites, auf die ich gestoßen bin, scheinen dies zu empfehlen, um einen Prozess im Hintergrund durchzuführen.

Wenn ich dies jedoch versuche, bekomme ich wilde Dinge mit dem Programmfluss, der "Hintergrund" -Prozess zeigt weiterhin Eingaben auf dem Bildschirm an, und ich bin mir wirklich nicht sicher, wohin ich von hier aus gehen soll.

Dies ist meine Implementierung des Codes, was sicher falsch ist. Ich frage mich nur, ob dieses ganze Enkelkind sogar die Route ist, die ich nehmen muss, und wenn ja, was ist mit meinem Code los?

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 }

Ps Um klar zu sein, ich brauche den Prozess, den ich im Hintergrund ausführe, um nie wieder einen Sound zu machen, auch wenn es eine unendliche Schleife von Druckaussagen oder so hat. Ich möchte nur sicherstellen, dass es immer noch im Hintergrund über PS -A oder so läuft.

Entschuldigung für die verwirrende Erklärung Ich weiß einfach nicht, wie ich sie besser erklären soll.

Danke im Voraus

Pps Ich werde es implementieren, damit jeder nachfolgende Befehl den booleschen Wert von "Hintergrund" bestimmt. Entschuldigung für die Verwirrung

War es hilfreich?

Lösung

Sie möchten das Doppel nicht verwenden.fork() Methode in einer Shell - dh zum Schreiben von Daemons, die speziell der Aufsicht durch die Shell entkommen möchten, die sie leitete.

Stattdessen der Weg, um das Verhalten von zu duplizieren & In vorhandenen Muscheln ist anzurufen fork(), dann im Kinderruf setpgid(0, 0); das Kind in ein neues zu bringen Prozessgruppe. Der Elternteil fährt einfach weiter (vielleicht nach dem Drucken des PID des Kindes) - es ruft nicht an wait().

Jedes Terminal kann nur eine Vordergrundprozessgruppe haben, die die Prozessgruppe ist, die derzeit die Ausgabe an das Terminal senden darf. Dies bleibt die Prozessgruppe, in der Ihre Schale Mitglied ist, sodass Ihre Schale im Vordergrund bleibt.

Wenn eine Hintergrundprozessgruppe versucht, aus dem Terminal aus zu lesen, wird ein Signal gesendet, um es zu stoppen. Die Ausgabe an das Terminal ist noch erlaubt - dies ist normal (versuchen Sie es ls & in Ihrer regulären Hülle). Um die zu implementieren fg Befehl in Ihrer Shell benötigen Sie die tcsetpgrp() Funktionieren Sie, um die Vordergrundprozessgruppe zu ändern.

Sie werden auch anrufen wollen waitpid() mit dem WNOHANG Option regelmäßig Option - sagen wir sofort, bevor Sie die Shell -Eingabeaufforderung anzeigen. Auf diese Weise können Sie erkennen, wann der Hintergrundprozess beendet oder gestoppt wurde (oder alternativ können Sie das verarbeiten SIGCHLD Signal).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top