如何存储进程ID并将其杀死?

时间:2013-12-07 23:27:15

标签: c linux kill pid

我在shell中处理后台进程时遇到了麻烦。我将pids存储在一个数组中,然后当我调用'jobs'时,它应该遍历数组,如果数字不是0,如果它仍然存活,它会打印,如果没有,它应该删除PID。我的结果非常不稳定。有人能看出我做错了吗?谢谢 结果:

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$ 

第一个文件是main,第二个文件是我的函数文件

/*
  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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你怎么知道你的(背景)工作是否已经死亡?你在前台工作wait - 所以你知道他们什么时候完成 - 但你不处理后台工作。无论你是杀了孩子还是他们最终自己过期(例如在例子中睡不着觉),你都不会知道。这也是您在输出列表中看到的内容。

解决这个问题的一种方法是为SIGCHLD设置信号处理程序,并在它们死亡时为它们设置waitpid。然后更新您的作业数组。或者其中的一些变化。