Привет!
есть сложный, многоцикличный, хорошо жрущий память код, написанный на С++ под linux.
будучи раз запущенным — он может работать до суток а то и двое.
Терпеть такое не хочется — нужно как то оградить его время работы.
Вставлять во все циклы (а их много!) проверку на таймер — да еще и как то определять
способы корректного выхода из них, а потом еще и из функций, в которых они написаны...
брррр... страх как не хочется.
Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса)
а сдохни-ка ты гад))). Типа kill -9 this->PID.
форкаться, чтоб в этом втором процессе следить за временем и слать kill, не хочется, ибо
по определению fork(), порожденный таким образом процесс имеет всю память,
стек и т.п. вещи, подобные/равные исходному — а т.к. исходный процесс многожрущий память
и т.п. то получается что я ради какого-то там мнимого убийства одного страшного процесса,
буду "рождать" еще такого же монстра, что и существующий процесс, но при этом пользу
выполняющего наиминимальнейшую если не сказать еще меньше...
что предложат в таком случае уважаемые форумчане?
Еше уточнение — решение можно принять — тока в коде С++. Т.е. никаких там bash/shell
скриптов, юниксовых хитростей. Процесс должен как то умереть из самого себя.
Код этого должен быть с++/boost/stl(тут рассматриваются варианты))))) и при этом не создавать
никакой "тяжелой" копии моего "страшного" процесса...
Re: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
16.04.11 07:45
Оценка:
еще доуточню)))
Ща вот подумал, а если можно придумать какой-нить скрипт, который можно простым exec'ом послать
на параллельное выполнение относительно текущего процесса, ну и типа внутри скрипта мы будем
ждать время таймера, а потом пошлем сигнал "КАПУТ" процессу, который его поймает, напишет
соответствующее предупреждение "в мир" и "сложит мирно лапки", то это вариант и вполне хороший.
Тока вот как все это грамотно написать)))
но если что еще есть у вас на примете — с благодарностью приму.
Re: убить процесс из этого же процесса по таймауту
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, Аноним, Вы писали:
JR>В начале main поставить таймер (timeSetEvent), в его обработчике вызвать ExitProcess.
WinAPI в linux, ага :D
Re[3]: убить процесс из этого же процесса по таймауту
Здравствуйте, Аноним, Вы писали:
А>Привет! А>есть сложный, многоцикличный, хорошо жрущий память код, написанный на С++ под linux. А>Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса) А>а сдохни-ка ты гад))). Типа kill -9 this->PID.
Поскольку всё работает по *nix, то можно так: в начале программы написать
alarm(86400); // или любое другое время
И не перехватывать SIG_ALARM.
Через 86400 секунд придёт соответствующий сигнал и программа благополучно умрёт. Отмена таймера:
alarm(0);
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: убить процесс из этого же процесса по таймауту
Здравствуйте, Аноним, Вы писали:
А>форкаться, чтоб в этом втором процессе следить за временем и слать kill, не хочется, ибо А>по определению fork(), порожденный таким образом процесс имеет всю память, А>стек и т.п. вещи, подобные/равные исходному — а т.к. исходный процесс многожрущий память А>и т.п. то получается что я ради какого-то там мнимого убийства одного страшного процесса, А>буду "рождать" еще такого же монстра, что и существующий процесс, но при этом пользу А>выполняющего наиминимальнейшую если не сказать еще меньше...
А>что предложат в таком случае уважаемые форумчане?
учить матчасть. форкаться ты будешь в самом начале процесса и получишь копию использующую немного памяти. заодно это и более надёжное решение, чем тред
Люди, я люблю вас! Будьте бдительны!!!
Re[2]: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
16.04.11 13:00
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:
BZ>учить матчасть. форкаться ты будешь в самом начале процесса и получишь копию использующую немного памяти. заодно это и более надёжное решение, чем тред
именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той
гранью, когда можно было бы сказать, что процесс кушает совсем ничего. Увы, там где мне надо ввести таймаут — там уже
ДОХ... короче много памяти съедено...
Re[3]: убить процесс из этого же процесса по таймауту
А>именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той А>гранью, когда можно было бы сказать, что процесс кушает совсем ничего.
ты живешь в pre-copy on write эру?
Re[2]: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
16.04.11 13:20
Оценка:
Здравствуйте, frogkiller, Вы писали:
F>Здравствуйте, Аноним, Вы писали:
А>>Привет! А>>есть сложный, многоцикличный, хорошо жрущий память код, написанный на С++ под linux. А>>Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса) А>>а сдохни-ка ты гад))). Типа kill -9 this->PID.
F>Поскольку всё работает по *nix, то можно так: в начале программы написать F>
alarm(86400); // или любое другое время
F>И не перехватывать SIG_ALARM.
F>Через 86400 секунд придёт соответствующий сигнал и программа благополучно умрёт. Отмена таймера: F>
alarm(0);
супер)) кажется то, что надо. А можно узнать — как бы мне всеж перехватить этот сигнал, ибо мне
ну кровь из носу в лог надо занести описание действия убивания по таймауту.
Я так понимаю — эт можно будет сделать тока в обработчике сигнала...
Т.е. типа "убиться об стенку" мне надо с пояснительной запиской для всего мира)))))
Re[3]: убить процесс из этого же процесса по таймауту
А>супер)) кажется то, что надо. А можно узнать — как бы мне всеж перехватить этот сигнал, ибо мне А>ну кровь из носу в лог надо занести описание действия убивания по таймауту. А>Я так понимаю — эт можно будет сделать тока в обработчике сигнала... А>Т.е. типа "убиться об стенку" мне надо с пояснительной запиской для всего мира)))))
Да, нужно поставить обработчик сигнала, и там писать свою пояснительную записку и делать exit.
А вообще
man 2 signal
man 2 alarm
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[4]: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
16.04.11 13:40
Оценка:
Здравствуйте, dilmah, Вы писали:
А>>именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той А>>гранью, когда можно было бы сказать, что процесс кушает совсем ничего.
D>ты живешь в pre-copy on write эру?
да, увы, бывают и такие гадости/странности.
короче условия я описал, шаг влево-вправо = расстрел.
хотите верьте, хотите нет.
Re[2]: убить процесс из этого же процесса по таймауту
А>Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса) А>а сдохни-ка ты гад))). Типа kill -9 this->PID.
Посмотрите на alarm
Re[4]: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
18.04.11 18:35
Оценка:
Здравствуйте, frogkiller, Вы писали:
..... F>Да, нужно поставить обработчик сигнала, и там писать свою пояснительную записку и делать exit.
F>А вообще F>
man 2 signal
F>man 2 alarm
так, сделано)))
static volatile sig_atomic_t timeout_data = 0;
void timer_handler(int signum)
{
warning("Program was interrupted after %1% seconds run", timeout_data);
fflush(stdout);
exit(1);
}
int Command :: run( <args> )
{
int ret_code = 0;
timeout_data = Config::instance()->get_int(Config::timeout);
if (timeout_data > 0) {
/* Install timer_handler as the signal handler for SIGVTALRM. */struct sigaction sa;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction(SIGVTALRM, &sa, NULL);
/* Configure the timer to expire after timeout_data' sec... */struct itimerval timer;
timer.it_value.tv_sec = timeout_data;
timer.it_value.tv_usec = 0; //microsec should not be used.
/* ... and disable it after it expires. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
/* Start a virtual timer. It counts down whenever this process is executing as a task. */
setitimer(ITIMER_VIRTUAL, &timer, NULL);
/* Display the correct message about this timeout. */
std::stringstream warn_msg;
warn_msg << "Set max execution time to " << timeout_data << " seconds";
if (timeout_data>=1800)
warn_msg << "(" << fixed << setprecision (1) << ((double)timeout_data)/3600 << " hours)";
warning("%s", warn_msg.str());
}
все работает)))) тока вопрос возник такого плана:
этим таймером я обложил мой "толстый" код, который хоть и трудно, но делает
свое дело)))) Соответственно, часто таймер не "играет свою роль" и это ок,
но как быть если сложится такая ситуация:
таймер утрированно стоит на 10 сек.
программа запускается, таймер включается, код работает. "Толстый" код
срабатывает за 9 сек. Потом идет код "окончания работы", длящийся, ну ... сек.3)))
Т.е. получается 9+3=12 что > 10. Т.е. прерывание сработает и прога аварийно завершится...
НО!!! Но я хочу, чтоб таймер отсчитывал секунды тока для "толстого" кода.
Т.е. я хочу после 9 сек. работы этого кода "отключить" тикание таймера.
Ибо последующий код не важно как долго работает...
Так вот я не понял как это правильно отключить тот тип таймера, что я выбрал.
Re[5]: убить процесс из этого же процесса по таймауту
От:
Аноним
Дата:
19.04.11 09:26
Оценка:
А>все работает)))) тока вопрос возник такого плана:
.... А>Так вот я не понял как это правильно отключить тот тип таймера, что я выбрал.
уточню — убить таймер и вернуть назад обработчик сигнала.
Re: убить процесс из этого же процесса по таймауту
Я не уверен, что это по Вашей теме, но всё же поделюсь опытом.
У меня на рабочей станции установлен пакет Condor, который предназначен для управления вычислительным кластером. Таким образом у меня на компьютере работает "кластер" из четырёх виртуальных "компьютеров" (по числу ядер).
Когда мне нужно запустить какую-нибудь числодробилку, и это нельзя сделать на институтском вычкластере, я запускаю её на рабочей машине через Condor. Что мне это даёт:
— Работа задачи протоколируется (во сколько начали, когда закончили и т.д.).
— Задача может быть прервана (например при перезагрузке или выключении компьютера) и потом продолжена без потерь данных, прозрачно для работающей программы.
— Можно запустить сколько угодно задач на расчёт, реально работать будут только 4, остальные встанут в очередь. Когда очередная задача завершится, её место занимает другая из очереди.
— Можно задать максимальное время счёта (Ваш случай).
— Если задач много, им можно назначать приоритеты.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, dilmah, Вы писали:
D>>ты живешь в pre-copy on write эру?
А>да, увы, бывают и такие гадости/странности.
А>короче условия я описал, шаг влево-вправо = расстрел. А>хотите верьте, хотите нет.
Dilmah попытался тебе тонко намекнуть, но у него получилось слишком уж тонко.
Под линуксом fork() процесса, занимающего много памяти, скушает на удивление мало ресурсов. Память между процессом-родителем и потомком будет расшарена. Только когда кто-нибудь из них начнет писать в память, будет создана копия той страницы, куда он писал, и потребление памяти в системе начнет расти.
Если твой долгоиграющий процесс интенсивно работает с памятью (не только читает, но и пишет в нее), после fork() в дочернем процессе можно память почистить (поудалять все данные, оставить только таймер). Освободившиеся страницы памяти будут возвращены в систему (там чуть сложнее, но в первом приближении работать будет так).
Впрочем, если решение с alarm() устраивает — париться с форками, конечно, не стоит.