Эквивалент getppid для получения дочернего pid

getppid() возвращает идентификатор процесса родительского процесса.

Поскольку любой данный процесс может иметь только одного родителя в любое время. Возвращение из getppid имеет смысл.

Есть ли эквивалентный системный вызов getChildPid?

Я знаю, что у процесса может быть много детей, но в моем случае я уверен, что у моего процесса будет только один ребенок в любой момент времени. Итак, в моем случае имеет смысл иметь системный вызов, как указано выше.

Редактировать: дочерний объект создается из внешней библиотеки, которая не предоставляет pid, возвращенный fork(),

3 ответа

У процесса может быть много детей, и нет смысла иметь вызов, который вернул бы только одного из них. Наиболее широко используемый механизм - сохранить возвращенный pid из fork,

Некоторые API не работают и не выставляют pid ребенка - в MacOS, AuthorizationExecuteWithPrivileges это пример. Это совершенно неправильно API, чтобы не дать вам дочерний pid, потому что вы должны быть в состоянии waitpid на нем, чтобы очистить зомби!

Для этих сломанных API вот обходной путь (используемый, например, Chrome). В псевдокоде:

pid_t sneakyFork(std::vector<const char*> args) {

  std::vector<const char*> newArgs = makeVect(
    "/usr/bin/perl","-w", "-e", 
    "printf \"%s,%s\\n\", $$, getppid();" 
    "$ENV{PATH} = '/usr/bin:/bin';" 
    "delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};" 
    "if ($#ARGV >= 0 and $ARGV[0] =~ /^(\\/.*)$/)" 
    "{ $ARGV[0] = $1;" 
    "  for ($i=1; $i <= $#ARGV; $i++)" 
    "  { $ARGV[$i] =~ /^(.*)$/; $ARGV[$i] = $1; }" 
    "  die unless exec { $ARGV[0] } @ARGV; }",
    (char*)0
  );
  newArgs.insert(newArgs.end(), args.begin(), args.end());
  newArgs.push_back(0);

  int pipe = nasty_library_call_with_stdout_inherited(newArgs);

  char buf[1024];
  read(pipe, &buf); // error checking...
  pid_t pid, ppid;
  parseBuf(buf, &pid, &ppid); // strchr for ',' and strtoul
  if (ppid == getpid())
    return pid; // we're the parent, the trick worked
  else
    return -1;
}

Вы можете сохранить следующую структуру. Теперь, когда вы делаете fork(), проверьте возвращаемое значение (PID). Если он ненулевой (больше нуля), то это родительский процесс. Теперь скопируйте этот идентификатор процесса в массив.

typedef struct
{

   char process[128];
   pid_t current_pid;
   pid_t child_pid[127];
   unsigned  int child_pid_index;
}my_pid_record;


  my_pid_record sample;


  if( ( p = fork()) > 0 )
  {
     printf("I am a parent process\r\n");
     sample.current_pid = getpid();
     strcpy(sample.process,argv[0]);
     sample.child_pid[child_pid_index] = p;
     child_pid_index++;
     /** basically write this information on the disk **/
     /** This is your lookup table **/
     fwrite(file, sample....)
     flush();
  }

else

{
    printf("I am child process..\r\n");

    /** whenever you do fork ..do this routine **/



}

Выполните get() и set () для чтения из файла. Вы сможете получить его. Это хороший вопрос с точки зрения дизайна, возможно, я бы сделал обертку для вилки. Вместо вызова fork вызовите мою функцию.

Другие вопросы по тегам