Ответ 1
Прочтите страницу руководства для ulimit
в системах unix. Существует встроенная оболочка, которую вы можете вызвать перед запуском исполняемого файла или (в разделе 3 руководства) вызов API с тем же именем.
Есть ли способ легко ограничить приложение C/С++ на определенный объем памяти (30 мб или около того)? Например: если мое приложение пытается загрузить файл 50 МБ в память, оно умрет/распечатает сообщение и закроет/и т.д.
По общему признанию, я могу постоянно проверять использование памяти для приложения, но было бы немного легче, если бы он просто умер с ошибкой, если бы я пошел выше.
Любые идеи?
Платформа не является большой проблемой, windows/linux/любой компилятор.
Прочтите страницу руководства для ulimit
в системах unix. Существует встроенная оболочка, которую вы можете вызвать перед запуском исполняемого файла или (в разделе 3 руководства) вызов API с тем же именем.
В Windows вы не можете установить квоту для использования памяти процесса напрямую. Однако вы можете создать объект задания Windows, установить квоту для объекта задания и затем назначить процесс этому объекту задания.
В bash используйте ulimit builtin:
bash$ ulimit -v 30000
bash$ ./my_program
-v принимает 1K блоков.
Update:
Если вы хотите установить это из своего приложения, используйте setrlimit. Обратите внимание, что man-страница для ulimit(3)
явно указывает, что она устарела.
Переопределите все API-интерфейсы malloc и предоставите обработчики для нового/удаления, чтобы вы могли хранить память и генерировать исключения, когда это необходимо.
Не уверен, что это еще проще и экономит, чем просто контролировать память через API-интерфейсы, предоставленные операционной системой.
Вы можете ограничить размер виртуальной памяти вашего процесса, используя системные ограничения. Если вы обрабатываете это количество, оно будет убито сигналом (думаю, SIGBUS).
Вы можете использовать что-то вроде:
#include <sys/resource.h>
#include <iostream>
using namespace std;
class RLimit {
public:
RLimit(int cmd) : mCmd(cmd) {
}
void set(rlim_t value) {
clog << "Setting " << mCmd << " to " << value << endl;
struct rlimit rlim;
rlim.rlim_cur = value;
rlim.rlim_max = value;
int ret = setrlimit(mCmd, &rlim);
if (ret) {
clog << "Error setting rlimit" << endl;
}
}
rlim_t getCurrent() {
struct rlimit rlim = {0, 0};
if (getrlimit(mCmd, &rlim)) {
clog << "Error in getrlimit" << endl;
return 0;
}
return rlim.rlim_cur;
}
rlim_t getMax() {
struct rlimit rlim = {0, 0};
if (getrlimit(mCmd, &rlim)) {
clog << "Error in getrlimit" << endl;
return 0;
}
return rlim.rlim_max;
}
private:
int mCmd;
};
И затем используйте его так:
RLimit dataLimit(RLIMIT_DATA);
dataLimit.set(128 * 1024 ); // in kB
clog << "soft: " << dataLimit.getCurrent() << " hard: " << dataLimit.getMax() << endl;
Эта реализация кажется немного многословной, но она позволяет вам легко и чисто устанавливать разные пределы (см. ulimit -a
).