LINUX.ORG.RU

Ограничение процессов


0

0

Задача: требуется запускать подчиненные процессы, ограничивая их по времени и по памяти. Ограничить по времени достаточно просто (fork -> usleep -> kill), а как ограничить по памяти - пока не разобрался.
Пока придумал вариант: поставить таймер и по таймеру отслеживать через getrusage затраченную память, в случае чего - убивать, но это выглядит как-то костыльно и затратно. Есть ли более простые способы?

Ответ на: комментарий от Deleted

Если сделать setrlimit -> fork, то дочерний процесс наследует лимиты родительского?

rexadecimal
() автор топика
Ответ на: комментарий от Deleted

Хотя я понял, что этого делать setrlimit перед fork и так не надо, спасибо.

rexadecimal
() автор топика
Ответ на: комментарий от rexadecimal

> У нас в детском саду с августа занятия!

Если не будешь в течение семестра бухать и прогуливать занятия, если не начнёшь сдавать лабы в начале декабря, то вырастешь скучным ботаником!

mv ★★★★★
()
Ответ на: комментарий от mv

>Если не будешь в течение семестра бухать и прогуливать занятия, если не начнёшь сдавать лабы в начале декабря, то вырастешь скучным ботаником!

пожалей преподавателей они тоже люди и должны же они кому-то автоматы поставить

dimon555 ★★★★★
()
Ответ на: комментарий от mv

Куда там бухать и прогуливать, мне родители запрещают :-(

rexadecimal
() автор топика

> Ограничить по времени достаточно просто (fork -> usleep -> kill)

Бгг.

> поставить таймер и по таймеру отслеживать через getrusage

getrusage уже умеет работать с живыми процессами?

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Надо было мне указать: ограничения могут быть меньше секунды, а setrlimit, как я понял, не умеет работать с лимитами меньше секунды?

rexadecimal
() автор топика
Ответ на: комментарий от rexadecimal

> ограничения могут быть меньше секунды, а setrlimit, как я понял, не умеет работать с лимитами меньше секунды?

Тогда, ИМХО, ты приплыл :) То есть можно придумать что-нибудь типа запуска дочернего процесса под ptrace, и периодический вызов getrusage от его имени, но для лабараторной это сложновато.

Ну или использовать контроллеры - вроде они уже есть в свежих ядрах.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> что не все указанные лимиты энфорсятся

в смысле?

> сам процесс может задрать себе лимит.

выше hard limit не прыгнет.

true_admin ★★★★★
()
Ответ на: комментарий от tailgunner

Так в чем проблема-то форкнуться, в дочернем - exec, а в родительском - usleep-kill?

Это, кстати, не лабораторная ).

rexadecimal
() автор топика
Ответ на: комментарий от Valeriy_Onuchin

У меня всё нормально:

#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>


int main(void) {
    struct rlimit rlim;
    rlim.rlim_cur = 10*1024*1024;
    rlim.rlim_max = 10*1024*1024;

    int res = setrlimit(RLIMIT_AS,&rlim);
    if (res) {
        err(1, "ZHOPA");
    }

    for (int x=0; x<100; x++) {
        void *ptr = malloc(1024*1024);
        if (!ptr) {
            err(2, "malloc failed on step %d", x);
            break;
        }
    }

    printf("O_O limit has been broken\n");
}
true_admin ★★★★★
()
Ответ на: комментарий от rexadecimal

> Так в чем проблема-то форкнуться, в дочернем - exec, а в родительском - usleep-kill?

В том, что usleep родительского процесса не имеет ровно никакого отношения к времени исполнения дочернего процесса // К.О.

> Это, кстати, не лабораторная ).

Тогда контроллеры.

tailgunner ★★★★★
()
Ответ на: комментарий от true_admin

> У меня всё нормально:

Потому что у тебя тот лимит, который легко энфорсится. Поставь RLIMIT_RSS и попробуй еще раз.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Потому что у тебя тот лимит, который легко энфорсится. Поставь RLIMIT_RSS и попробуй еще раз.

эммм...

       RLIMIT_RSS
              Specifies the limit (in pages) of the process's resident set (the number  of  virtual
              pages resident in RAM).  This limit only has effect in Linux 2.4.x, x < 30, and there
              only affects calls to madvise() specifying MADV_WILLNEED.

в смысле оно действительно то надо трогать RLIMIT_RSS с такими своеобразными ограничениями?

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> в смысле оно действительно то надо трогать RLIMIT_RSS с такими своеобразными ограничениями?

Вообще-то RSS - это единственный вид потребления памяти, который имеет смысл ограничивать :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ну вот вы говорите, что они в свежих ядрах, а аналогичные системы (ограничивающие, по времени и по памяти) существуют достаточно давно - это тестирующие системы на олимпиадах по программированию, например. Проблема в том, что все нормальные, кажется, закрыты.

rexadecimal
() автор топика
Ответ на: комментарий от rexadecimal

> Ну вот вы говорите, что они в свежих ядрах

А я что - неправ, и в свежих ядрах их нет?

> аналогичные системы (ограничивающие, по времени и по памяти) существуют достаточно давно

*shrug* вероятно, и что? Найди и пользуйся, уж всяко лучше, чем usleep + kill.

> это тестирующие системы на олимпиадах по программированию, например

Там лимитов и watchdog более чем хватит %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ну ладно, спасибо ). После всего этого возникает еще один вопрос: как узнать, вылетела ли программа из-за ограничения по времени или по памяти?
Надеюсь, не слишком много я их задал :)?

rexadecimal
() автор топика
Ответ на: комментарий от rexadecimal

> Ну ладно, спасибо ). После всего этого возникает еще один вопрос: как узнать, вылетела ли программа из-за ограничения по времени или по памяти?

если по времени ты сам отслеживаешь время её исполнения а по лимитам на уровне системы - какие тут могут быть вопросы? она ж не сама умирает по времени. по лимитам - waitpid() и смотри, от чего она померла.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от rexadecimal

> После всего этого возникает еще один вопрос: как узнать, вылетела ли программа из-за ограничения по времени или по памяти?

ХЗ, ХЗ. Я бы считал, что, если программа ушла по SIGXCPU или SIGKILL, то это перерасход процессорного времени, если по SIGSEGV или SIGABRT - то по памяти. Но это подразумевает использование setrlimit, который тебя вроде как не устраивает по точности.

tailgunner ★★★★★
()
Ответ на: комментарий от rexadecimal

> Ну ладно, спасибо ). После всего этого возникает еще один вопрос: как узнать, вылетела ли программа из-за ограничения по времени или по памяти?

Запусти свою программу на первом Пеньтиуме с 32мб памяти, нехай там без таймеров и лимитов мучается.

> Надеюсь, не слишком много я их задал :)?


Говно вопрос, заходи ещё!

mv ★★★★★
()
Ответ на: комментарий от true_admin

> В каких ОС можно лимит на RSS выставлять?

Насколько я понимаю, в NT и в свежих Linux.

> И что делать с процесами которые его превысили?

Просто не позволять им превысить предел.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Просто не позволять им превысить предел.

Это как? вот стек вырос, vss "перешёл" в rss. Или процесс решил таки воспользоваться аллоцированной памятью и vss тоже превратился в rss при записи.

true_admin ★★★★★
()
Ответ на: комментарий от tailgunner

Фига се ты ушёл от ответа. Ну давай рассмотрим конкретую ситуацию. Стэк немного вырос, что делать дальше? Только убить процесс. По крайней мере я больше ничего не вижу.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> Фига се ты ушёл от ответа.

А я должен прочитать лекцию о том, что такое виртуальная память?

> Стэк немного вырос, что делать дальше? Только убить процесс.

Неверно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> А я должен прочитать лекцию о том, что такое виртуальная память?

Хватит пары слов.

> Неверно.

Расскажи как правильно :).

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

>> А я должен прочитать лекцию о том, что такое виртуальная память?

> Хватит пары слов.

Я скажу даже 4: VMM может уменьшить RSS.

> Расскажи как правильно :).

После увеличения стека на 1 страницу в своп отправляется какая-нибудь другая.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А нахрена тогда ставить лимиты если всё что не вписывается улетает в своп? Только винты дёргать.

Собстно в memcg лимит так и ставится:anon pages+своп. И оно прибивает процесс которые не вписывается в это(через oom).

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> А нахрена тогда ставить лимиты если всё что не вписывается улетает в своп?

А нахрена вообще лимиты?

> Собстно в memcg лимит так и ставится:anon pages+своп

Значит, до сих пор ниасилили реализовать лимит на RSS. Задача нетривиальная, да и VMM в линуксе - дерьмо, если верить слухам.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Значит, до сих пор ниасилили реализовать лимит на RSS

Хотя, если верить Documentation/cgroups/memory.txt, RSS-контроллер таки реализован. Правда, они почему-то считают, что RSS состоит только из anon pages.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> А нахрена вообще лимиты?

чтобы на мультиюзерских тачках один юзер другим жизнь не портил. Или же в случае когда у тебя много сервисов крутится. Забив своп можно дос устроить.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

>> А нахрена вообще лимиты?

> чтобы на мультиюзерских тачках один юзер другим жизнь не портил.

Не-а. Точнее, может быть, они для этого придумывались, но с этой задачей они справляются очень плохо.

А вот контейнеры как раз для этого %) И в том числе они обязаны уметь ограничивать потребление физической памяти.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.