// таймера, после чего он фактически и запускается
struct itimerspec itime;
nsec2timespec(&itime.it_value, millisec * 1000000ull);
itime it_interval = itime.it_value;
if (!(ok = (timer_settime(timer, 0, &itime, NULL) == 0))) return;
}
// признак того, что объект создан успешно и его поток запущен:
bool OK(void) { return ok; }
bool statistic(void) { return st; }
};
int thrblock.code = _PULSE_CODE_MINAVAIL;
// функция потока объекта
void* syncthread(void *block) {
thrblock *p = (thrblock*)block;
struct _pulse buf;
pthread_attr_t attr;
while(true) {
// ожидание пульса от периодического таймера объекта
MsgReceivePulse(p->chid, &buf, sizeof(struct _pulse), NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// восстановить приоритет целевой функции до уровня того,
// кто ее устанавливал, вызывая конструктор
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr, &p->param);
// запуск целевой функции в отдельном "отсоединенном" потоке
pthread_create(NULL, &attr, p->func, NULL);
if (p->statistic()) ++p->sync;
}
}
// 'пустой' обработчик сигнала SIGINT (реакция на ^С)
inline static void empty(int signo) {}
int main(int argc, char **argv) {
// с этой точки стандартная реакция на ^С отменяется...
signal(SIGINT, empty);
// массив целевых функций
void(*funcs[])(void) = { &mon1, &mon2, &mon3 };
// периоды их синхросерий запуска
int period[] = { 317, 171, 77 };
// приоритеты, на которых отрабатывается реакция
// синхросерий на каждый из таймеров синхросерий
int priority[] = { 15, 5, 25 };
int num = sizeof(funcs) / sizeof(*funcs);
// запуск 3-х синхронизированных последовательностей
// выполнения (созданием объектов)
thrblock** tb = new (thrblock*)[num];
for (int i = 0; i < num; i++) {
tb[i] = new thrblock(funcs[i], period[i],
priority[i], true);
if (!tb[i]->OK())
perror("synchro thread create"), exit(EXIT_FAILURE);
}
// ... а теперь ожидаем ^С.
pause();
// подсчет статистики и завершение программы
cout << endl << "Monitoring finalisation!" << endl;
// вывод временных интервалов будем делать в миллисекундах:
const double n2m = 1000000.;
for (int i = 0; i < num, i++) {
timestat *p = &tb[i]->sync;
!(*p); // подсчет статистики по объекту
cout << i << '\t' << p->num << "\t=> " << p->mean / n2m << " [" <<
p->tmin / n2m << "..." << p->tmax / n2m << "]\t~" << p->disp / n2m <<
" (" << p->disp / p->mean * 100 << "%)" << endl;
}
return EXIT_SUCCESS;
}