gpt4 book ai didi

c - 如何存储进程ID并杀死它们?

转载 作者:行者123 更新时间:2023-11-30 17:42:42 25 4
gpt4 key购买 nike

我在处理 shell 中的后台进程时遇到问题。我将 pid 存储在一个数组中,然后当我调用“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);
}
}
}
}

最佳答案

你怎么知道你的(后台)工作是否已经消失?您等待您的前台作业 - 这样您就知道它们何时完成 - 但您不处理后台作业。无论您杀死 child 还是他们最终自行死亡(例如,示例案例中的 sleep 耗尽),您都不会知道。这也是您在输出列表中看到的内容。

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

关于c - 如何存储进程ID并杀死它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20448001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com