Программирование в стандарте POSIX


Пример 12.36


/* * * * * * * * * * * * * * * * * * * * */ /* Программа вызывает функции обработки */ /* и контролирует время их выполнения */ /* с помощью интервального таймера */ /* * * * * * * * * * * * * * * * * * * * */

#include <stdio.h> #include <sys/time.h> #include <signal.h> #include <setjmp.h>

/* Период интервального таймера (в секундах) */ #define IT_PERIOD 1

static jmp_buf buf_env; /* Буфер для функций setjmp и longjmp */

static double s; /* Результат функций обработки данных */

/* Функция обработки срабатывания таймера реального времени */ /* (сигнал SIGALRM) */ static void proc_sigalrm (int dummy) { printf ("Текущий результат текущей функции обработки данных: %g\n", s); longjmp (buf_env, 1); }

/* Первая функция обработки данных */ /* (вычисляет ln (2)) */ static void proc_data_1 (void) { double d = 1; int i;

s = 0; for (i = 1; i <= 100000000; i++) { s += d / i; d = -d; } }

/* Вторая функция обработки данных */ /* (вычисляет sqrt (2)) */ static void proc_data_2 (void) { s = 1; do { s = (s + 2 / s) * 0.5; } while ((s * s - 2) > 0.000000001); }

int main (void) { /* Массив указателей на функции обработки данных */ void (*fptrs []) (void) = {proc_data_1, proc_data_2, NULL}; /* Указатель на указатель */ /* на текущую функцию обработки данных */ void (**tfptr) (void); /* Вспомогательная временная переменная */ void (*tmpfptr) (void); struct itimerval itvl; struct sigaction sact; sigset_t sset; int i;

/* Установим реакцию на сигнал SIGALRM */ if (sigemptyset (&sset) < 0) { perror ("SIGEMPTYSET"); return (1); }

sact.sa_handler = proc_sigalrm; sact.sa_flags = SA_NODEFER; /* Не блокировать SIGALRM */ /* в функции обработки этого сигнала */ sact.sa_mask = sset; if (sigaction (SIGALRM, &sact, NULL) < 0) { perror ("SIGACTION"); return (2); }

/* На всякий случай сделаем таймер реального времени периодическим */ itvl.it_interval.tv_sec = IT_PERIOD; itvl.it_interval.tv_usec = 0;

/* Цикл вызова функций обработки данных. */ /* Выполним его дважды */ for (i = 0; i < 2; i++) { tfptr = fptrs; (void) setjmp (buf_env); /* Сюда вернется управление после срабатывания таймера */ while ((tmpfptr = *tfptr++) != NULL) { /* Даже если предыдущая функция обработки данных */ /* закончилась до того, как сработал таймер, */ /* обеспечим текущей функции полный интервал */ itvl.it_value.tv_sec = IT_PERIOD; itvl.it_value.tv_usec = 0; if (setitimer (ITIMER_REAL, &itvl, NULL) < 0) { perror ("SETITIMER"); return (3); } (*tmpfptr) (); printf ("Результат текущей функции обработки данных: %g\n", s); } }

return 0; }

Листинг 12.36. Пример программы, использующей интервальные таймеры реального времени для управления ходом выполнения программы.

Закрыть окно






Начало  Назад  Вперед