【问题标题】:How to store process IDs and kill them?如何存储进程 ID 并杀死它们?
【发布时间】:2013-12-07 23:27:15
【问题描述】:

我在处理 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$ 

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

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

【问题讨论】:

    标签: c linux kill pid


    【解决方案1】:

    您如何知道您的(背景)工作是否已终止?您 wait 在您的前台工作 - 所以您知道他们何时完成 - 但您不处理后台工作。无论您是杀死孩子还是他们最终自己过期(例如,在示例案例中睡眠耗尽),您都不会知道。这也是您在输出列表中看到的内容。

    解决此问题的一种方法是为 SIGCHLD 和waitpid 在它们死亡时设置信号处理程序。然后更新您的工作数组。或者它的一些变体。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      相关资源
      最近更新 更多