Как ограничить время выполнения функции в C / POSIX? - PullRequest
2 голосов
/ 14 сентября 2010

Подобно этому вопросу , я хотел бы ограничить время выполнения функции - предпочтительно с точностью до микросекунды - в C. Я полагаю, что исключения C ++ могут использоваться для достижения аналогичного результата это решение Python. Хотя он не идеален, такой подход совершенно недоступен на простом C.

Интересно, а как я могу прервать выполнение функции через определенный промежуток времени в C в системе Posix? Для относительно простых ситуаций немного «глупый бизнес» работает просто отлично, но это добавляет изрядное количество кода, ортогонального к решению проблемы. Допустим, у меня есть такая функция:

void boil(egg *e) {
    while (true)
    do_boil(e);
}

Я хочу запустить варить на яйце *, прерывая его каждые 50 мкс, чтобы проверить, что-то вроде этого:

egg *e = init_egg();
while (true) {
    preempt_in(50, (void) (*boil), 1, e);
    /* Now boil(e) is executed for 50μs, 
       then control flow is returned to the
       statement prior to the call to preempt_in.
     */
    if (e->cooked_val > 100)
        break;
}

Я понимаю, что для этого можно использовать pthreads, но я скорее заинтересован в том, чтобы избежать их использования. Я мог бы переключаться между ucontext_t в обработчике SIGALRM, но стандарт POSIX отмечает, что использование setcontext / swapcontext не должно использоваться в обработчике сигналов, и, действительно, я отмечаю различное поведение между системами Linux и Solaris при этом.

Возможен ли этот эффект для достижения? Если да, то портативным способом?

Ответы [ 3 ]

1 голос
/ 14 сентября 2010

Вы можете либо использовать потоки, либо сделать так, чтобы функция опрашивала таймер (или глобальную переменную, установленную обработчиком SIGALRM), затем сохраняла его состояние и выходила по истечении выделенного времени. Использование ucontext_t устарело и никогда не должно использоваться в новом коде, а тем более - в обработчиках сигналов.

0 голосов
/ 02 октября 2010

Просто отметим, что общая возможность, которую вы ищете здесь, называется принудительное исполнение затрат .Например, см. Эту статью Wellings или Leung, et.Великая книга Аллаха .Ответы выше направлены на достижение этого в пользовательском пространстве;некоторые RTOS или языки поддерживают его (не linux) в качестве общего механизма.

Одной из примеров ОС, обеспечивающей это, является AUTOSAR OS (спецификация связана) .Обратите внимание, что эта ОС обеспечивает принудительное выполнение времени выполнения , что немного отличается от принудительного выполнения крайнего срока. принудительное выполнение времени выполнения становится все сложнее, так как она полагается на некоторую способность измерять фактические затраты (обычнос аппаратным взаимодействием).Учитывая сложность современных процессоров, это сложно и дорого измерить - не говоря уже о том, что значение измерений (из-за нелинейного выполнения и всевозможных других интересных вещей) трудно интерпретировать - и, следовательно, сложное событие для вычисления (оценка наихудшего или общего) конкретного случая времени выполнения кода.

Немного не по теме, но здесь Ada предоставляет более строгий набор возможностей на уровне языка, который вам не поможет,но вы могли бы выяснить, как эти требования Ada были реализованы в Linux.Спецификация языка Ada уникальна в предоставлении обоснования документа, см. Раздел упреждающий прерывание в реальном времени в качестве отправной точки.

0 голосов
/ 14 сентября 2010

Решение, которое я желаю, внезапно приходит ко мне: иди! Я установлю точку перехода сразу после функции, которую я хочу ограничить, установлю таймер и в обработчике сигнала, который имеет дело с SIG * ALRM, просто перейду к инструкции после функции.

...