Вход/Регистрация
QNX/UNIX: Анатомия параллелизма
вернуться

Цилюрик Олег Иванович

Шрифт:

// функция потока объекта

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;

}

Вся функциональность программы сосредоточена в одном классе —

thrblock
, который может в неизменном виде использоваться для разных приложений. Необычной особенностью объекта этого класса является то, что он выполнен в технике «активных объектов», навеянной поверхностным знакомством с языками программирования школы Н. Вирта — ActiveOberon и Zormon. В ней говорится, что конструктор такого объекта не только создает объект данных, но и запускает (как вариант) отдельный поток выполнения для каждого создаваемого объекта. В нашем случае задача потоковой функции состоит в вызове целевой функции, адрес которой был передан конструктору объекта в качестве одного из параметров. [26]

26

Здесь применена только простейшая форма «активного объекта»: гораздо сложнее, к примеру, определить деструктор такого объекта. Но именно в своем простейшем виде это многообещающая техника активных объектов.

  • Читать дальше
  • 1
  • ...
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: