Re[6]: убить процесс из этого же процесса по таймауту
От: frogkiller Россия  
Дата: 19.04.11 20:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Так вот я не понял как это правильно отключить тот тип таймера, что я выбрал.

А>уточню — убить таймер и вернуть назад обработчик сигнала.

А чем alarm(timeout)/alarm(0) не устроил?

Ну и в man setitimer написано:

The element it_value is set to the amount of time remaining on the timer, or zero if the timer is disabled.

Курица — это инструмент, с помощью которого одно яйцо производит другие.
Re[4]: убить процесс из этого же процесса по таймауту
От: brankovic  
Дата: 19.04.11 20:51
Оценка:
Здравствуйте, dilmah, Вы писали:
BZ>>>заодно это и более надёжное решение, чем тред
J>>Почему?
D>ну как, треды то не изолированы -- в результате один тред может зафакапить тот тред который должен мониторить и убить если нужно.

Надо попасть точно в маленький кусочек в стеке спящего треда. По-моему от дедлока в хэндлере сигнала и гемороя больше и вероятность самого события больше.
Re[7]: убить процесс из этого же процесса по таймауту
От: Аноним  
Дата: 20.04.11 05:18
Оценка:
Здравствуйте, frogkiller, Вы писали:

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


А>>>Так вот я не понял как это правильно отключить тот тип таймера, что я выбрал.

А>>уточню — убить таймер и вернуть назад обработчик сигнала.

F>А чем alarm(timeout)/alarm(0) не устроил?


F>Ну и в man setitimer написано:

F>

The element it_value is set to the amount of time remaining on the timer, or zero if the timer is disabled.


alarm использует реальное время, a мне надо виртуальное, тиковое, то, которое таймеры высокого разрешения выдают.
чтоб учитывалось тока то время, когда процесс исполняется как задача.
Ибо загрузка на серваках может привести к тому, что скока-то времени процесс будет ждать своей очереди не выполняясь.
А значит нет нужды тикать таймеру.

И да, перечитав еще раз MANтры — я нашел, выделенное вами))) спс!

получилось так:
static volatile sig_atomic_t timeout_data = 0;
void timer_handler(int signum)
{
  warning("Execution was interrupted after %1% seconds run", timeout_data); 
  fflush(stdout);
  exit(1);
} 

void set_timer_signal(int sec)
{
  /* Install the signal_handler for SIGVTALRM... */
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = &timer_handler;
  sa.sa_flags = SA_RESETHAND;
  sigaction(SIGVTALRM, &sa, NULL);
  
  /* ... and a virtual timer. */
  //configure the timer to expire after timeout_data' sec...
  struct itimerval timer;
  timer.it_value.tv_sec = sec;
  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 " << sec << " seconds";
  if (sec>=1800)
    warn_msg << "(" << fixed << setprecision (1) << ((double)sec)/3600 << " hours)";
  warning("%s", warn_msg.str());
} 

void cancel_timer_signal(int& sec)
{
  /* Cancel a virtual timer. */
  struct itimerval cancel_timer;
  memset(&cancel_timer, 0, sizeof(cancel_timer));
  setitimer(ITIMER_VIRTUAL, &cancel_timer, NULL);
  /* The same for the signal_handler. */
  struct sigaction cancel_sa;
  memset(&cancel_sa, 0, sizeof(cancel_sa));
  cancel_sa.sa_handler = SIG_DFL;
  sigaction(SIGVTALRM, &cancel_sa, NULL);
  
  warning("Execution timer for %1% seconds was canceled", sec);
  sec=-1;//for not cancelling timer twice or more times.
}

int Command :: run( <args> )
{
  int ret_code = 0;

  timeout_data = Config::instance()->get_int(Config::timeout);
  if (timeout_data > 0) set_timer_signal(timeout_data);

//толстый код

  if (timeout_data > 0) cancel_timer_signal((int&)timeout_data);

}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.