2017-03-31 17 views
0

我需要创建n来自同一父母的孩子,并让他们运行,同时父母无限地询问要发送给某个孩子的信号。我让父母创建那些儿童,但他们完成了执行,所以我让他们进入一段时间(1)循环。问题是,当我试图杀死任何一个孩子时,它变成了一个僵尸进程,而不是实际终止它的执行。我猜这是因为父母仍在等待孩子终止执行,他们不会发送退出状态。所以...首先,我真的需要让孩子进入一个无限的while循环,让他们在父母询问信号时运行吗?如果我这样做,我该如何避免这种“永不终止执行”的问题?我需要找到一种让孩子们退出while循环的方式,并发送实际的“完成执行”信号,因为我认为我不能使用wait(),因为孩子们从未真正完成跑步,他们只是由父母终止。使用fork()创建“后台运行”的孩子并用信号杀死他们每个人

谢谢。 PS:在Linux中运行。这是我的代码

int main(){ 
    int i; 
    pid_t parent = getpid(); 
    pid_t pid[4]; 
    printf("parent with pid %d\n", parent); 

    for(i = 0; i < 5; i++){ 
     pid[i] = fork(); 
     if(pid[i] < 0){ 
      perror("Error in fork."); 
      exit(1); 
     } else if(pid[i] == 0 && getppid() == padre) { 
      printf("Number: %d pid %d, parent: %d\n", i, getpid(), getppid()); 
      while(1); 
     } 
    } 

    if(getpid() == padre){ 
     while(1){ 
      printf("Enter pid and signal:\n"); 
      int x, y; 
      scanf("%d", &x); // pid 
      scanf("%d", &y); // signal 
      printf("you did: kill(%d, %d)\n", x, y); 
      kill(x, y); 
     } 
    } 
    return 0; 
} 

编辑: 最终代码的答案来实现:https://github.com/sebasura/sistope

+4

读取有关['wait'](http://man7.org/linux/man-pages/man2/wait.2.html)系统调用,并且它兄妹。 –

+2

杀死后的'waitpid()'调用将是一个好的开始。 – mshildt

+3

而不是'while(1);',你可能更喜欢'暂停()'。 –

回答

4

的问题是,当我试图杀死任何一个孩子,就变成了僵尸进程,而不是实际终止它的执行。

嗯,是的,没有。成为僵尸通常是当进程终止时发生的,直到该进程被父进程收集为止。一个僵尸在进程表中占用一点空间,但它不是运行,因此不消耗CPU。

我猜这是因为父母仍在等待孩子终止执行,他们不会发送退出状态。

不,这是因为kill()只是发送一个信号。您需要使用wait()函数之一 - 也许是waitpid() - 才能真正收集终止的孩子。

所以......首先,我真的需要让孩子进入一个无限的while循环,让他们在父母询问信号时运行吗?

号的孩子可以使用sigwait()或其变体的一个等待信号从一组指定,或pause()中止执行待收到终止处理或触发信号处理函数的任何信号。但是,请注意,有些信号默认不含这两种信号,因此sigwait()可能是更好的选择。

如果我这样做,我该如何避免这种“永不终止执行”的问题?

孩子必须因接收信号而终止。这已经发生在你身上,因为孩子们正在变成僵尸。使用你现在的代码,它可能取决于你发送了哪个信号,但是,有些人的默认处理不会终止进程。

+0

好吧,我需要做的是:在while(1)循环中取出while(1),并用pause()或sigwait()取代它,然后在kill()后收集带有waitpid()对?我不知道如何使用sigwait(),我有点用waitpid()丢失。我需要使用的唯一信号是SIGUSR1,SIGUSR2和SIGTERM,所以我认为pause()会很好。我试着用waitpid(x,&state,WNOHANG | WUNTRACED)收集孩子;但它对僵尸孩子毫无意义。我真的不知道如何实现这些变化,因为我没有完全理解函数v_v。 – Sebasuraa

+0

@Sebasuraa,是的,除了绝对不使用'WNOHANG',并且可能不使用'WUNTRACED'。前者特别会引入竞争条件 - 如果它在父节点的waitpid()'调用之前恰好结束,则会收集子节点,否则不会。如果必要的话,父母没有比等待孩子终止任何事情更好的了,所以这就是它应该做的。 –

0

谢谢大家,我做到了。我使用pause()而不是while(1)

与毁伤后,我用这个:

int state; 
waitpid(pid, &state, 0); 

这是一门功课的一部分,所以我会在到期日之后上传的代码,使他们不惩罚我要分享它或东西。

再次感谢。 编辑: 下面是最终代码https://github.com/sebasura/sistope

相关问题