2013-12-07 5 views
0

쉘에서 백그라운드 프로세스를 처리하는 데 문제가 있습니다. pids를 배열에 저장하고 나서 'jobs'을 호출하면 배열을 반복하고 번호가 0이 아니고 여전히 살아 있으면 인쇄하고 그렇지 않으면 그것을 제거해야합니다. pid. 매우 일관성없는 결과가 나타납니다. 누군가 내가 잘못하고있는 것을 볼 수 있습니까? 감사합니다 결과 :프로세스 ID를 저장하고 죽이는 방법은 무엇입니까?

ben$ sleep 5 & 
Ben: started job 30290 
ben$ jobs 
30290 
ben$ jobs 
30290 
ben$ jobs 
30290 
ben$ kill 30290 
ben$ kill 30290: No such process 
jobs 
ben$ jobs 
ben$ sleep 4s & 
Ben: started job 30547 
ben$ jobs 
30547 
ben$ kill 30547 
ben$ jobs 
30547 
ben$ jobs 
30547 
ben$ 

첫 번째 파일은 기본이고, 두 번째는 제 기능이 (배경) 작업이 죽었을 경우 어떻게 알 수 있습니까

/* 
    Shell 1 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <stdbool.h> 
#define DELIMS " \t\r\n" 
int main (int argc, char *argv[]) { 
    int ids[10]; 

    initializeArray(ids); 

    while (1) { 
     char line[100]; 
     char *temp; 
     char *split[15]; 
     pid_t pid; 
     bool background=false; 

    printf("ben$ "); 

    //if cmd-d, exit shell 
    if(!fgets(line, sizeof(line), stdin)) { 
     printf("\n"); 
     break; 
    } 

     line[strlen(line)-1]='\0'; 
     temp=strtok(line," "); 


     if (strcmp(temp, "exit") == 0) { 
     break; 
     } 
     else if (strcmp(temp, "cd") == 0) { 
     char *arg = strtok(0, DELIMS); 

     if (!arg) { 
      fprintf(stderr, "cd missing argument.\n"); 
     } 
     else { 
      chdir(arg); 
     } 

     } 
     else if (strcmp(temp, "jobs") == 0) { 
     printJobs(ids); 
     continue; 
     } 

     else { 
     int i=0; 
     while(temp != NULL) { 
     split[i]=temp; 
     temp=strtok(NULL," "); 
     i++; 
     } 
     split[i] = NULL; 
     if(strcmp(split[i-1], "&")==0) { 
     // printf("should do in background"); 
     split[i-1]='\0'; 
     background=true; 
     } 

     char *args[i]; 
     int j; 
     for(j=0; j < i; j++){ 
     args[j]=split[j]; 
     } 


     pid=fork(); 

     if(pid==0) { 
     if(background) { 
        fclose(stdin); 
        fopen("/dev/null","r"); 
     } 
     execvp(args[0], args); 
     printf("This should not happen\n"); 
     } 
     else { 
     if(!background) { 
      // printf("Not in background\n"); 
      wait(&pid); 
     } 
     else { 
      printf("Ben: started job %d\n",pid); 
      insertPid(ids,pid); 
      background=false; 
     } 
    } 
    } 

    } 
    return 0; 
} 


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


void initializeArray(int ids[]); 
void insertPid(int ids[],int pid); 
void removePid(int ids[],int pid); 
void printJobs(int ids[]); 


void initializeArray(int ids[]) { 
    int i; 
    for(i=0;i<10;i++) { 
     ids[i]=0; 
    } 

} 

void insertPid(int ids[],int pid) { 
    // printf("inserting\n"); 
    int i=0; 


    while(i<10) { 
     if(ids[i]==0) { 
      ids[i]=pid; 
      return; 
     } 
     i++; 
    } 
    printf("insert into list error"); 
    return; 
} 
void removePid(int ids[],int index) { 
    // printf("removing %d\n",pid); 
     ids[index]=0; 
     return; 
} 
void printJobs(int ids[]) { 
    // printf("printing\n"); 
    int i; 
    int pid; 
    for(i=0;i<10;i++) { 

     if(ids[i] != 0) { 
      // printf("job value %d",ids[i]); 
      pid=ids[i]; 
      if(kill(pid,0) == 0) { 
       printf("%d\n",pid); 
      } 
      else{ 
       removePid(ids,i); 
      } 
     } 
    } 
} 

답변

0

파일입니까? 전경에서 일하는 사람이 wait인데, 완료되었을 때 알 수 있기 때문에 배경 작업은 처리하지 않습니다. 자녀를 죽이든 결국 결국 만료 되든 (예 : 수면이 부족한 경우) 알 수 없습니다. 그것이 출력 목록에서도 볼 수 있습니다.

이 방법에 접근하는 한 가지 방법은 SIGCHLD에 대한 신호 처리기를 설정하고 이들이 소멸 될 때 waitpid을 설정하는 것입니다. 그런 다음 작업 배열을 업데이트하십시오. 또는 그것의 약간 변이.