#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. Однако не утруждайте себя уничтожением дочерних элементов. Когда у них закончится память, они умрут сами по себе.