Эквивалент 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 вызовите мою функцию.