2016-04-12 12 views
0

Ich habe ein paar Zombie-Prozesse, die im Hintergrund laufen (nicht mehr funktionieren) und ich bin mir nicht sicher, wie ich sie töten soll. Ich mache eine Mini-Shell, also ist es im Grunde wie das Terminal, aber meine eigene Version davon.Ernten Zombies? [C]

Hier ist mein Code:

#include <stdio.h> 
#include <string.h> 
#include <stddef.h> 
#include "main.h" 

int main() { 

    /* Declared variables */ 
    char buff[100]; 
    char* args[20]; 
    int arguments = 20; 

    /* Boolean value */ 
    int done = 0; 

    while(done != 1) { 
     /* Print directory */ 
     printf("%s>", getcwd(0,0)); 
     /* Gets input */ 
     fgets(buff, 100, stdin); 

     /* Checks to see if anything was entered */ 
     if (buff[0] == '\n') { 
      printf("Error: Enter a command! (Example: ls -l)\n"); 
     } else { 
      parseArgs(buff, args, 20, &arguments); 

      if (*args[0] == '\n') { 
       printf("Error: Enter a command! (Example: ls -l)\n"); 
      } else if (strcmp(args[0], "exit") == 0) { 
       done = 1; 
      } else if (strcmp(args[0], "cd") == 0) { 
       /* Changes the directory */ 
       int dir = chdir(args[1]); 
       if (dir != 0) { 
        printf("That directory isn't valid!\n"); 
       } 
      } else { 

       int background = 0; 
       int count = 0; 

       /* Create a new process */ 
       int process = fork(); 
       if (process == -1) { 
        printf("Error: Unable to create a process!"); 
       } else if (process == 0) { 

        /* Run user input */ 
        int res = execvp(args[0], args); 
        if (res == -1) { 
         printf("\nError: Enter a command! (Example: ls -l)\n"); 
         done = 1; 
        } 

        int reapingInfo; 
        waitpid(process, &reapingInfo, 0); 
       } 
      } 
     } 
    } 
return (0); 
} 

Hier ist, was ich als eine Ausgabe bekommen, wenn ich ls -l ein paar Mal laufen und den Befehl ausführen: ps:

20978 pts /6  00:00:00 bash 
21049 pts /6  00:00:00 main 
21050 pts /6  00:00:00 ls <defunct> 
21051 pts /6  00:00:00 ls <defunct> 
21062 pts /6  00:00:00 ps 

Irgendwelche Hinweise auf Wie ernten Sie diese defunct Prozesse?

Antwort

2

Ihre Logik folgende fork() sieht nicht richtig aus. Sie haben else if (process == 0), und in diesem Zweig (im untergeordneten Prozess) führen Sie ein neues Programm und nach, die Sie versuchen, waitpid() aufrufen. Da execvp nie zurückkehrt, wenn die Ausführung erfolgreich ist, wird Ihre waitpid die meiste Zeit nie aufgerufen.

Ich denke, Sie vermissen eine else irgendwo. Die waitpid sollte im übergeordneten (der Prozess, in dem fork() einen streng positiven Wert zurückgegeben) getan werden. Dann wird waitpid die Zombies ernten; das ist seine Aufgabe.

(By the way, wenn execvp ausfällt, wollen Sie wahrscheinlich _exit() nennen. Letting das Kind bis zum Abschluss weiter laufen wird wahrscheinlich nicht richtig. Zum Beispiel alle Daten in stdio Puffer zweimal geschrieben werden konnte.)

0

Hier können Sie ein Beispiel für die Verwendung von fork/exec/waitpid sehen, die in Ihrem Code funktionieren sollte:

/* Create a new process */ 
int process = fork(); 
if (process == -1) { 
    printf("Error: Unable to create a process!"); 
} else if (process == 0) { 
    /* Run user input */ 
    int res = execvp(args[0], args); 
    /* execvp only returns if it fails, not need to check if res == -1 */ 
    printf("\nError: Enter a command! (Example: ls -l)\n"); 
    exit(1); /* kill this process, if exec fails! */ 
} else { 
    int reapingInfo; 
    waitpid(process, &reapingInfo, 0); 
} 
Verwandte Themen