Как ограничить объем памяти, который может использовать созданная программа на C

#c #process

#c #процесс

Вопрос:

В моей программе на c я собираюсь запускать другие программы. Если эти программы используют более определенного объема памяти, я хочу, чтобы моя программа завершала их процессы. Как это можно сделать?

Вероятно, я буду использовать execv для запуска программ.

Комментарии:

1. На какой платформе? C не может сделать это сам; он не знает концепции процессов. Но ваша платформа, вероятно, использует.

2. @Billy Учитывая, что он планирует использовать execv, я предполагаю, что он работает под Unix. Но, хороший момент.

3. @Etienne: В исходном вопросе не было этого лакомого кусочка.

Ответ №1:

Предполагая, что вы используете систему POSIX, вы можете ограничить это, вызвав setrlimit(2) after fork() . Например:

 if (fork() == 0) {
    struct rlimit limits;
    limits.rlim_cur = 10000000; // set data segment limit to 10MB
    limits.rlim_max = 10000000; // make sure the child can't increase it again
    setrlimit(RLIMIT_DATA, amp;limits);
    execv(...);
}
  

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

Комментарии:

1. Вы можете просто использовать целое число для const struct rlimit* второго параметра?

2. 1 за то, что он более полный (и, следовательно, более полезный), чем мой ответ.

3. Как мне запустить программу перед этим кодом? Запускается ли программа в конце?

4. Правильно, вы используете execv() или что-то еще обычным способом для запуска дочернего процесса. Главное, что нужно запомнить, это установить ограничение после fork() и перед exec() .

5. Что, если я хочу добавить еще одну вещь, которую следует учитывать: время. Скажем, я хочу ограничить, как долго программы могут использовать более 10 МБ памяти. Можно ли это изменить, чтобы сделать это?

Ответ №2:

Прочитайте о setrlimit функции. Вы, вероятно, хотите что-то вроде:

 #include <sys/resource.h>

struct rlimit limits;
limits.rlim_cur = // soft limit
limits.rlim_max = // hard limit
int err = setrlimit(RLIMIT_DATA, amp;limits);
if(err) ...
  

Предполагается, что вы пишете для Unix / Linux / BSD / Mac / и т.д., А не для Windows … что кажется хорошим предположением, поскольку вы используете execv .

Пара замечаний: мягкое ограничение ( rlim_cur ) может уведомлять процесс о превышении предела. Превышение жесткого предела ( rlim_max ) приводит malloc() к сбою, установленному errno на ENOMEM , что обычно приводит к завершению процесса. Прочитайте справочную страницу или попробуйте ее, чтобы увидеть, как это работает в вашей системе. Если стек увеличивается rlim_max , вы можете получить SIGSEGV сигнал.

Как правило, только корневой процесс может вызывать rlim_max . Обычный процесс может понизить rlim_max или установить rlim_cur значение в диапазоне от 0 до rlim_max .

Ответ №3:

В Linux вы, вероятно, захотите использовать setrlimit. Однако не утруждайте себя уничтожением дочерних элементов. Когда у них закончится память, они умрут сами по себе.