убить процесс из этого же процесса по таймауту
От: Аноним  
Дата: 16.04.11 07:31
Оценка:
Привет!
есть сложный, многоцикличный, хорошо жрущий память код, написанный на С++ под linux.
будучи раз запущенным — он может работать до суток а то и двое.
Терпеть такое не хочется — нужно как то оградить его время работы.
Вставлять во все циклы (а их много!) проверку на таймер — да еще и как то определять
способы корректного выхода из них, а потом еще и из функций, в которых они написаны...
брррр... страх как не хочется.

Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса)
а сдохни-ка ты гад))). Типа kill -9 this->PID.

форкаться, чтоб в этом втором процессе следить за временем и слать kill, не хочется, ибо
по определению fork(), порожденный таким образом процесс имеет всю память,
стек и т.п. вещи, подобные/равные исходному — а т.к. исходный процесс многожрущий память
и т.п. то получается что я ради какого-то там мнимого убийства одного страшного процесса,
буду "рождать" еще такого же монстра, что и существующий процесс, но при этом пользу
выполняющего наиминимальнейшую если не сказать еще меньше...

что предложат в таком случае уважаемые форумчане?

Еше уточнение — решение можно принять — тока в коде С++. Т.е. никаких там bash/shell
скриптов, юниксовых хитростей. Процесс должен как то умереть из самого себя.
Код этого должен быть с++/boost/stl(тут рассматриваются варианты))))) и при этом не создавать
никакой "тяжелой" копии моего "страшного" процесса...
Re: убить процесс из этого же процесса по таймауту
От: Аноним  
Дата: 16.04.11 07:45
Оценка:
еще доуточню)))

Ща вот подумал, а если можно придумать какой-нить скрипт, который можно простым exec'ом послать
на параллельное выполнение относительно текущего процесса, ну и типа внутри скрипта мы будем
ждать время таймера, а потом пошлем сигнал "КАПУТ" процессу, который его поймает, напишет
соответствующее предупреждение "в мир" и "сложит мирно лапки", то это вариант и вполне хороший.
Тока вот как все это грамотно написать)))

но если что еще есть у вас на примете — с благодарностью приму.
Re: убить процесс из этого же процесса по таймауту
От: brankovic  
Дата: 16.04.11 08:06
Оценка: 1 (1)
void suicide () {sleep (86400); exit (0);}

int main ()
{
   boost::thread (suicide);
   ...
Re: убить процесс из этого же процесса по таймауту
От: Jolly Roger  
Дата: 16.04.11 09:09
Оценка:
Здравствуйте, Аноним, Вы писали:

В начале main поставить таймер (timeSetEvent), в его обработчике вызвать ExitProcess.
"Нормальные герои всегда идут в обход!"
Re[2]: убить процесс из этого же процесса по таймауту
От: Flammable Россия  
Дата: 16.04.11 09:15
Оценка: +1 :)
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Аноним, Вы писали:


JR>В начале main поставить таймер (timeSetEvent), в его обработчике вызвать ExitProcess.

WinAPI в linux, ага :D
Re[3]: убить процесс из этого же процесса по таймауту
От: Jolly Roger  
Дата: 16.04.11 09:45
Оценка:
Здравствуйте, Flammable, Вы писали:

JR>>В начале main поставить таймер (timeSetEvent), в его обработчике вызвать ExitProcess.

F>WinAPI в linux, ага :D

Виновен, не заметил
"Нормальные герои всегда идут в обход!"
Re: убить процесс из этого же процесса по таймауту
От: frogkiller Россия  
Дата: 16.04.11 10:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет!

А>есть сложный, многоцикличный, хорошо жрущий память код, написанный на С++ под linux.
А>Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса)
А>а сдохни-ка ты гад))). Типа kill -9 this->PID.

Поскольку всё работает по *nix, то можно так: в начале программы написать
alarm(86400); // или любое другое время

И не перехватывать SIG_ALARM.

Через 86400 секунд придёт соответствующий сигнал и программа благополучно умрёт. Отмена таймера:
alarm(0);
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re: убить процесс из этого же процесса по таймауту
От: BulatZiganshin  
Дата: 16.04.11 11:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>форкаться, чтоб в этом втором процессе следить за временем и слать kill, не хочется, ибо

А>по определению fork(), порожденный таким образом процесс имеет всю память,
А>стек и т.п. вещи, подобные/равные исходному — а т.к. исходный процесс многожрущий память
А>и т.п. то получается что я ради какого-то там мнимого убийства одного страшного процесса,
А>буду "рождать" еще такого же монстра, что и существующий процесс, но при этом пользу
А>выполняющего наиминимальнейшую если не сказать еще меньше...

А>что предложат в таком случае уважаемые форумчане?


учить матчасть. форкаться ты будешь в самом начале процесса и получишь копию использующую немного памяти. заодно это и более надёжное решение, чем тред
Люди, я люблю вас! Будьте бдительны!!!
Re[2]: убить процесс из этого же процесса по таймауту
От: Аноним  
Дата: 16.04.11 13:00
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>учить матчасть. форкаться ты будешь в самом начале процесса и получишь копию использующую немного памяти. заодно это и более надёжное решение, чем тред


именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той
гранью, когда можно было бы сказать, что процесс кушает совсем ничего. Увы, там где мне надо ввести таймаут — там уже
ДОХ... короче много памяти съедено...
Re[3]: убить процесс из этого же процесса по таймауту
От: dilmah США  
Дата: 16.04.11 13:04
Оценка:
А>именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той
А>гранью, когда можно было бы сказать, что процесс кушает совсем ничего.

ты живешь в 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]: убить процесс из этого же процесса по таймауту
От: frogkiller Россия  
Дата: 16.04.11 13:37
Оценка:
Здравствуйте, Аноним, Вы писали:

F>>
alarm(86400); // или любое другое время


А>супер)) кажется то, что надо. А можно узнать — как бы мне всеж перехватить этот сигнал, ибо мне

А>ну кровь из носу в лог надо занести описание действия убивания по таймауту.
А>Я так понимаю — эт можно будет сделать тока в обработчике сигнала...
А>Т.е. типа "убиться об стенку" мне надо с пояснительной запиской для всего мира)))))

Да, нужно поставить обработчик сигнала, и там писать свою пояснительную записку и делать exit.

А вообще
man 2 signal
man 2 alarm
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[4]: убить процесс из этого же процесса по таймауту
От: Аноним  
Дата: 16.04.11 13:40
Оценка:
Здравствуйте, dilmah, Вы писали:


А>>именно зная матчасть я и описал МОЮ ТЕКУЩУЮ ситуацию. Т.е. те места кода, которые я могу изменить — они УЖЕ находятся за той

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

D>ты живешь в pre-copy on write эру?


да, увы, бывают и такие гадости/странности.

короче условия я описал, шаг влево-вправо = расстрел.
хотите верьте, хотите нет.
Re[2]: убить процесс из этого же процесса по таймауту
От: jazzer Россия Skype: enerjazzer
Дата: 18.04.11 02:10
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>заодно это и более надёжное решение, чем тред

Почему?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: убить процесс из этого же процесса по таймауту
От: sand7e Россия  
Дата: 18.04.11 02:56
Оценка:
Здравствуйте, Аноним, Вы писали:



А>Хочется просто как то время пришло — сказать самому себе (ну в рамках запущенного процесса)

А>а сдохни-ка ты гад))). Типа 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: убить процесс из этого же процесса по таймауту
От: andrey_nado  
Дата: 19.04.11 12:00
Оценка:
Я не уверен, что это по Вашей теме, но всё же поделюсь опытом.

У меня на рабочей станции установлен пакет Condor, который предназначен для управления вычислительным кластером. Таким образом у меня на компьютере работает "кластер" из четырёх виртуальных "компьютеров" (по числу ядер).

Когда мне нужно запустить какую-нибудь числодробилку, и это нельзя сделать на институтском вычкластере, я запускаю её на рабочей машине через Condor. Что мне это даёт:

— Работа задачи протоколируется (во сколько начали, когда закончили и т.д.).
— Задача может быть прервана (например при перезагрузке или выключении компьютера) и потом продолжена без потерь данных, прозрачно для работающей программы.
— Можно запустить сколько угодно задач на расчёт, реально работать будут только 4, остальные встанут в очередь. Когда очередная задача завершится, её место занимает другая из очереди.
— Можно задать максимальное время счёта (Ваш случай).
— Если задач много, им можно назначать приоритеты.
condor
Re[3]: убить процесс из этого же процесса по таймауту
От: dilmah США  
Дата: 19.04.11 12:36
Оценка:
BZ>>заодно это и более надёжное решение, чем тред
J>Почему?

ну как, треды то не изолированы -- в результате один тред может зафакапить тот тред который должен мониторить и убить если нужно.
Re[5]: убить процесс из этого же процесса по таймауту
От: chemey  
Дата: 19.04.11 13:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, dilmah, Вы писали:


D>>ты живешь в pre-copy on write эру?


А>да, увы, бывают и такие гадости/странности.


А>короче условия я описал, шаг влево-вправо = расстрел.

А>хотите верьте, хотите нет.

Dilmah попытался тебе тонко намекнуть, но у него получилось слишком уж тонко.

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

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

Впрочем, если решение с alarm() устраивает — париться с форками, конечно, не стоит.
Бзззззззжжжжж
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.