fork() и waitpid() не ждут ребенка

У меня возникли проблемы с тем, чтобы заставить waitpid работать, может кто-нибудь объяснить, что не так с этим кодом?

#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;

int main() {
    string filename_memory;
    decltype(fork()) pid;

    if (!(pid = fork())) {
        cout << "in child" << endl;
        sleep(1);
    }

    else {
        int status_child;

        do {
            waitpid(pid, &status_child, WNOHANG);
            cout << "waiting for child to finish" << endl;
        } while (!WIFEXITED(status_child));

        cout << "child finished" << endl;
    }

    return 0;
}

person Curious    schedule 13.12.2015    source источник
comment
Вы, вероятно, захотите проверить возвращаемое значение waitpid и прочитать status_child, только если возвращаемое значение равно pid, что-то вроде if (ret == pid && WIFEXITED(status_child)) break;   -  person Piotr Skotnicki    schedule 13.12.2015


Ответы (1)


Если функция wait() или waitpid() возвращается из-за того, что доступно состояние дочернего процесса, эти функции должны возвращать значение, равное идентификатору процесса-потомка, для которого сообщается о состоянии.

Если функция waitpid() была вызвана с установленным параметром WNOHANG в параметрах, у нее есть по крайней мере один дочерний процесс, указанный pid, для которого статус недоступен, и статус недоступен для любого процесса, указанного pid, возвращается 0. В противном случае должно быть возвращено (pid_t)-1 и установлено значение errno, указывающее на ошибку.

Это означает, что переменная status_child не имеет значения, пока waitpid не вернет pid дочернего элемента.

Вы можете исправить это, применив эти изменения:

int ret;
do {
    ret = waitpid(pid, &status_child, WNOHANG);
    cout << "waiting for child to finish" << endl;
} while (ret != pid || !WIFEXITED(status_child));

cout << "child finished" << endl;
person Alexguitar    schedule 13.12.2015