跟踪Unix中的子进程

use*_*828 2 c unix fork

我已经完成了一个C程序,它产生了许多进程,然后在短时间内杀死它们.我是新手,并试图弄清楚为什么我试图跟踪我的进程来杀死作品.我的指针pid_t* id指向cmd line参数创建时要求的进程ID数.

现在这是我的窘境.fork()返回child和parent的值,但是我找不到它是如何工作的固定顺序.它是先返回子值还是父值,还是未定义?

id[]阵列是为每个生成的进程相同,右(如在有未被催生n_child阵列)?

由于程序100%的时间都在工作,所以看起来父总是最后返回,因为这是在杀戮过程中存储在数组中的内容.这是一种"安全"的方式来跟踪流程(请记住,我不是在寻找最好的方式或任何东西,因为我确信有更好的方法)?似乎答案应该是否定的,并且如果我确定它是父级,我应该只设置数组.

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

#define MAX_N_CHILD 10

int main (int argc, char **argv) {
  int n_child, i;
  pid_t* id; 
  /* note: on a 32 bit machine, pid_t is defined as the __S32_TYPE,
     which is an int rather than a long */

  if (argc == 2) { 
    n_child = atoi (argv[1]); /* captures the command line argument */
    /* **NOTE** argv[0] is always the file name of this program */

    if (n_child > MAX_N_CHILD) {
      printf ("Too many children wanted!\n");
      return 0;
    }

  }
  else {
    printf ("Invalid number of arguments!\n");
    return 0;
  }

  id = malloc( sizeof(pid_t) * n_child );
  if(id == NULL)
  {
    return 0;
  }

  printf ("********  HELLO!  *********\n");
  printf ("parent %d(CPU#%d)\n", getpid(), sched_getcpu());


  /* create new process(es) */
  for(i = 0; i < n_child; ++i)
  {
    id[i] = fork(); 

    if (id[i] == -1) 
    {
      printf("Error: Process not created");
      return 0;
    }
    else if (id[i] == 0) { /* I'm the child */
      //execlp ("./dummy", "dummy", NULL); /* replace myself with a new program */
      sleep(2);
    }
    else
    { 
      continue; //Continue loop
    }

  } //End for

      /* Only the parent process should get here. */

      /* wait a little to let the child processes run before killing them */
      usleep(50000); /* sleep for 50000 microseconds */


      /* kill */
      for(i = 0; i < n_child; ++i)
      {
        printf ("killing %d\n", id[i]);
        kill (id[i], SIGKILL); /* SIGKILL is defined in signal.h */
      }

      //pkill -TERM -P id  //Only kills immediate children of parent

      printf ("All %d child processes killed!\n", n_child);
}
Run Code Online (Sandbox Code Playgroud)

BRP*_*ock 5

现在这是我的窘境.fork()返回child和parent的值,但是我找不到它是如何工作的固定顺序.它是先返回子值还是父值,还是未定义?

嗯......不......不太好.

这是fork(有效)发生的事情:

  • 您的单个进程将克隆到相同的子进程中.几乎所有属性都被复制了.
  • 但是,子进程将具有新的进程ID(pid)
  • 在子进程中, fork返回一个0.
  • 在父进程中, fork返回子进程的新pid.

来自两个返回fork发生同时,在这个过程中的两个不同的副本.实际上,它们之间的唯一区别是它们从中获得的结果fork.

没有顺序:这两个CPU内核几乎可以肯定ocuur在同样的时刻,甚至在单核心系统,他们将发生在任意顺序并有可能在同一时间内执行单一的机器代码指令,交错一个用另一个.

换句话说,顺序明确定义为同时发生.

在的时刻fork,有成为一切的两个副本.所以,一方面,是的,现在有n个数组副本id[]存在; 然而,每个孩子的副本将只有在它之前产生的孩子的id(甚至不是它自己的).

替换exec(execlp在这种情况下)sleep会导致程序徘徊在......非常奇怪的领域.你写/* Only the parent process should get here */,但这不是真的sleep.

使用exec*函数,您可以销毁进程的内容并使用新程序替换它(保持其pid和其他一些属性).假设exec没有失败,那么这是真的,你的程序将不再是孩子进程中的程序,并且不会达到该行;

但是,正如所写,你有一个奇怪的竞争条件.该sleepusleep可以设置程序将多长时间度过一个下限,但如果因为任何原因父进程没有移动速度不够快杀了孩子,那么孩子将开始尝试(编辑忘了这一点)结束了for循环并产生更多的孩子,然后互相杀害他们的新孩子.由于id[]每个孩子在fork编辑之前都被复制了,所以它会尝试杀死所有"兄弟姐妹",然后pid = 0为自己和它产生的额外孩子.

您还提到了问题中的产生线程,但您的问题代码中的任何内容都与线程无关.