Здравствуйте, Аноним, Вы писали:
А>>Так вот я не понял как это правильно отключить тот тип таймера, что я выбрал.
А>уточню — убить таймер и вернуть назад обработчик сигнала.
А чем 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.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Здравствуйте, 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);
}