Прежде всего, позвольте мне объяснить, как я могу придумать этот вопрос. Мой код выглядит так:
void *foo(void *data)
{
printf("foo pid %d\n", getpid());
sleep(2);
int res = system("echo haha");
printf("System result: %d\n", res);
return NULL;
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, foo, NULL);
int wstatus;
int p;
do {
p = waitpid(-1, &wstatus, 0);
if (p == -1) {
// This prints a bunch of "Errno 10 No child processes"
//printf("Errno %d %s\n", errno, strerror(errno));
} else {
break;
}
} while (1);
printf("Exited process: %d\n", p);
}
Я ожидаю, что system()
всегда будет возвращать 0. Однако программа дает мне один из этих сценариев ios:
foo pid 8793
хаха
Системный результат: 0
и
foo pid 8685
хаха
Выход из процесса: 8687
Системный результат: -1
На основании "man system" , говорят, что
- Если дочерний процесс не может быть создан или его состояние не может быть получено, возвращаемое значение равно -1.
Поскольку дочерний процесс всегда создается ("echo haha" в обоих случаях завершается успешно), я предполагаю, что завершение дочернего процесса, созданного в вызове system()
, случайно выбирается либо waitpid()
, либо system()
, что означает, что system()
возвращает 0, то waitpid()
возвращает -1, а если system()
возвращает -1, что означает, что ему не удалось получить идентификатор своего дочернего процесса, то waitpid()
возвращает идентификатор процесса, созданного system()
. * 10 45 *
На основании моего исследования system()
фактически вызывает fork()
, execl()
и waitpid()
в его реализации. Итак, мой вопрос: если system()
вызывает waitpid()
, то как получается, что завершение его дочернего процесса воспринимается процессом "прародителя", а не им самим? Если я сам реализую system()
, будет ли это иметь какое-то значение?
ОБНОВЛЕНИЕ
Видимо, ответ - , завершение дочернего процесса всегда происходит по вызову waitpid()
его «прямого» родительского процесса и, как предполагает ссылка , нет никакого способа для процесса напрямую wait()
для своих процессов-внуков . Таким образом, вопрос теперь больше похож на «как звонит system()
ведет себя так?».
ОБНОВЛЕНИЕ 2
Похоже, я неправильно понимаю system()
. Код выше в основном вызывает waitpid()
в двух потоках - основной поток и внутри foo()
(который вызывает system()
). Таким образом, есть два потока, которые вызывают waitpid()
одновременно, и только один из них завершается успешно.