Какие условия могут привести к сбою вызовов fork () или system () в Linux? - PullRequest
6 голосов
/ 12 мая 2009

И как можно выяснить, происходит ли какое-либо из них и приводит к ошибке, возвращаемой fork () или system ()? Другими словами, если fork () или system () возвращаются с ошибкой, что я могу проверить в Linux, чтобы определить причину этой конкретной ошибки?

Например:

  • Просто не хватает памяти (приводит к ошибке ENOMEM) - проверьте использование памяти с помощью 'free' и т. Д.
  • Недостаточно памяти для ядра, чтобы скопировать таблицы страниц и другую учетную информацию родительского процесса (приводит к ошибке EAGAIN)
  • Существует ли глобальный лимит процессов? (приводит к errno EAGAIN также?)
  • Есть ли ограничение на процесс для каждого пользователя? Как я могу узнать, что это такое?
  • ...

Ответы [ 2 ]

6 голосов
/ 12 мая 2009

А как можно узнать, происходит ли какой-нибудь из них?

Проверьте значение errno , если результат (возвращаемое значение) равен -1

Со страницы руководства по Linux:

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
В случае успеха PID дочернего процесса возвращается в родительском, а 0 возвращается в дочернем. В случае ошибки -1 возвращается в родительский процесс, дочерний процесс не создается и значение errno устанавливается соответствующим образом.

ОШИБКА
EAGAIN
Функция fork () не может выделить достаточно памяти, чтобы скопировать таблицы страниц родителя и выделить структуру задачи для дочернего элемента.
EAGAIN
Не удалось создать новый процесс, так как был обнаружен предел ресурса RLIMIT_NPROC вызывающей стороны. Чтобы превысить этот предел, процесс должен иметь возможность CAP_SYS_ADMIN или CAP_SYS_RESOURCE.
ENOMEM
Функция fork () не смогла выделить необходимые структуры ядра, так как объем памяти ограничен.

СООТВЕТСТВУЮЩИМ SVr4, 4.3BSD, POSIX.1-2001.

1 голос
/ 12 мая 2009

nproc в /etc/security/limits.conf может ограничивать количество процессов на пользователя.

Вы можете проверить наличие ошибок, проверив возврат с форка. 0 означает, что вы являетесь дочерним элементом, положительное число - это pid дочернего элемента и означает, что вы являетесь родителем, а отрицательное число означает, что ответвление не выполнено. Когда fork терпит неудачу, он устанавливает внешнюю переменную errno. Вы можете использовать функции в errno.h для его проверки. Обычно я просто использую perror, чтобы напечатать ошибку (с добавленным к ней текстом) в stderr.

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

int main(int argc, char** argv) {
    pid_t pid;

    pid = fork();
    if (pid == -1) {
        perror("Could not fork: ");
        return 1;
    } else if (pid == 0) {
        printf("in child\n");
        return 0;
    };

    printf("in parent, child is %d\n", pid);

    return 0;
}
...