Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Тут можно читать онлайн Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-osnet, издательство Петрополис, год 2001. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
  • Автор:
  • Жанр:
  • Издательство:
    Петрополис
  • Год:
    2001
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94656-025-9
  • Рейтинг:
    3.67/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform краткое содержание

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - описание и краткое содержание, автор Роб Кёртен, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Книга "Введение в QNX/Neutrino 2» откроет перед вами в мельчайших подробностях все секреты ОСРВ нового поколения от компании QNX Software Systems Ltd (QSSL) — QNX/Neutrino 2. Книга написана в непринужденной манере, легким для чтения и понимания стилем, и поможет любому, от начинающих программистов до опытных системотехников, получить необходимые начальные знания для проектирования надежных систем реального времени, от встраиваемых управляющих приложений до распределенных сетевых вычислительных систем

В книге подробно описаны основные составляющие ОС QNX/Neutrino и их взаимосвязи. В частности, уделено особое внимание следующим темам:

• обмен сообщениями: принципы функционирования и основы применения;

• процессы и потоки: базовые концепции, предостережения и рекомендации;

• таймеры: организация периодических событий в программах;

• администраторы ресурсов: все, что относится к программированию драйверов устройств;

• прерывания: рекомендации по эффективной обработке.

В книге представлено множество проверенных примеров кода, подробных разъяснений и рисунков, которые помогут вам детально вникнуть в и излагаемый материал. Примеры кода и обновления к ним также можно найти на веб-сайте автора данной книги, www.parse.com.

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - читать онлайн бесплатно полную версию (весь текст целиком)

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - читать книгу онлайн бесплатно, автор Роб Кёртен
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

POOL_FLAG_EXIT_SELF

Не делать возврат из функции thread_pool_start() и не включать вызывающий поток в пул.

POOL_FLAG_USE_SELF

Не делать возврат из функции thread_pool_start() , но включить вызывающий поток в пул.

0

Функция thread_pool_start() возвратится, новые потоки будут создаваться по мере необходимости.

Приведенное описание может показаться суховатым. Давайте рассмотрим пример.

В управляющей структуре пула потоков сконцентрируем наше внимание только на значениях параметров lo_water , increment и maximum :

/*

* tp1.с

*

* Пример с пулами потоков (1)

*

*/

#include

#include

#include

#include

#include

char *progname = "tp1";

void tag (char *name) {

time_t t;

char buffer[BUFSIZ];

time(&t);

strftime(buffer, BUFSIZ, "%T ", localtime(&t));

printf("%s %3d %-20.20s: ", buffer, pthread_self(), name);

}

THREAD_POOL_PARAM_T* blockfunc(

THREAD_POOL_PARAM_T *ctp) {

tag("blockfunc");

printf("ctp %p\n", ctp);

tag("blockfunc");

printf("sleep (%d);\n", 15 * pthread_self());

sleep(pthread_self() * 15);

tag("blockfunc");

printf("Выполнили sleep\n");

tag("blockfunc");

printf("Возвращаем 0x%08X\n",

0x10000000 + pthread_self());

return((void*)(0x10000000 + pthread_self()));

// Передано handlerfunc

}

THREAD_POOL_PARAM_T* contextalloc(

THREAD_POOL_HANDLE_T *handle) {

tag("contextalloc");

printf("handle %p\n", handle);

tag("contextalloc");

printf("Возвращаем 0x%08X\n",

0x20000000 + pthread_self());

return ((void*)(0x20000000 + pthread_self()));

// Передано blockfunc

}

void contextfree(THREAD_POOL_PARAM_T *param) {

tag("contextfree");

printf("param %p\n", param);

}

void unblockfunc(THREAD_POOL_PARAM_T *ctp) {

tag("unblockfunc");

printf("ctp %p\n", ctp);

}

int handlerfunc(THREAD_POOL_PARAM_T *ctp) {

static int i = 0;

tag("handlerfunc");

printf("ctp %p\n", ctp);

if (i++ > 15) {

tag("handlerfunc");

printf("Более 15 операций, возвращаем 0\n");

return (0);

}

tag("handlerfunc");

printf("sleep (%d)\n", pthread_self() * 25);

sleep(pthread_self() * 25);

tag("handlerfunc");

printf("Выполнили sleep\n");

tag("handlerfunc");

printf("Возвращаем 0x%08X\n",

0x30000000 + pthread_self());

return (0x30000000 + pthread_self());

}

main() {

thread_pool_attr_t tp_attr;

void *tpp;

memset(&tp_attr, 0, sizeof(tp_attr));

tp_attr.handle = (void*)0x12345678;

// Передано contextalloc

tp_attr.block_func = blockfunc;

tp_attr.unblock_func = unblockfunc;

tp_attr.context_alloc = contextalloc;

tp_attr.context_free = contextfree;

tp_attr.handler_func = handlerfunc;

tp_attr.lo_water = 3;

tp_attr.hi_water = 7;

tp_attr.increment = 2;

tp_attr.maximum = 10;

if ((tpp =

thread_pool_create(&tp_attr, POOL_FLAG_USE_SELF)) ==

NULL) {

fprintf(stderr,

"%s: Ошибка thread_pool_create, errno %s\n",

progname, strerror(errno));

exit(EXIT_FAILURE);

}

thread_pool_start(tpp);

fprintf(stderr,

"%s: возврат из thread_pool_start; errno %s\n",

progname, strerror(errno));

sleep(3000);

exit(EXIT_FAILURE);

}

После установки параметров мы вызываем функцию thread_pool_create() для создания пула потоков. Эта функция возвращает указатель на управляющую структуру пула потоков ( tpp ), который мы проверяем на равенство NULL (что указало бы на ошибку). И, наконец, мы вызываем функцию thread_pool_start() , передав ей эту самую управляющую структуру tpp .

Я указал флаг POOL_FLAG_USE_SELF, что означает, что поток, вызвавший функцию thread_pool_start() , будет рассматриваться как доступный для ввода в пул. Таким образом, на момент старта пула в нем есть только один поток. Поскольку значение параметра lo_water равно 3, библиотека немедленно создаст еще increment потоков (в нашем случае — 2). С этого момента в пуле будет три (3) потока, и все они будут находиться в режиме блокирования. Условие по параметру lo_water удовлетворено, потому что число потоков в режиме блокирования действительно не меньше lo_water , условие по параметру hi_water удовлетворено, потому что число потоков в режиме блокирования действительно не больше hi_water ; и, наконец, также удовлетворено условие по параметру maximum, потому что общее число потоков не превышает его значения. Допустим теперь, что один из потоков, находящихся в режиме блокирования, разблокируется (например, в серверном приложении — при получении сообщения). Это означает, что один из трех потоков перейдет из режима блокирования в режим обработки. Счетчик блокированных потоков уменьшится, и его значение упадет ниже значения параметра lo_water . Это переключит триггер lo_water и заставит библиотеку создать ещё increment (2) потоков. Таким образом, у нас будет всего 5 потоков (4 в режиме блокирования, и 1 — в режиме обработки).

Пусть далее разблокируется еще несколько потоков. Давайте предположим, что на этот момент еще ни один из потоков, находящихся в режиме обработки, еще не завершил свои дела. Ниже приведена таблица, в которой иллюстрируется весь процесс, начиная с исходного состояния:

Событие Режим обработки Режим блокирования Всего потоков
Исходное состояние 0 1 1
Срабатывание триггера lo_water 0 3 3
Разблокирование 1 2 3
Срабатывание триггера lo_water 1 4 5
Разблокирование 2 3 5
Разблокирование 3 2 5
Срабатывание триггера lo_water 3 4 7
Разблокирование 4 3 7
Разблокирование 5 2 7
Срабатывание триггера lo_water 5 4 9
Разблокирование 6 3 9
Разблокирование 7 2 9
Срабатывание триггера lo_water 7 3 10
Разблокирование 8 2 10
Разблокирование 9 1 10
Разблокирование 10 0 10

Видно, что библиотека проверяет параметр lo_water , и по мере необходимости увеличивает число потоков на значение параметра increment , но только до тех пор, пока число потоков не достигнет предельного значения — параметра maximum (именно поэтому число в столбце «Всего потоков» никогда не превышает 10, даже когда условие по параметру lo_water перестает выполняться).

Это означает, что однажды наступает момент, когда потоков в режиме блокирования больше не остается. Предположим теперь, что потоки, находящиеся в режиме обработки, завершают свои дела. Посмотрим, что при этом произойдет с триггером параметра hi_water .

Событие Режим обработки Режим блокирования Всего потоков
Завершение обработки 9 1 10
Завершение обработки 8 2 10
Завершение обработки 7 3 10
Завершение обработки 6 4 10
Завершение обработки 5 5 10
Завершение обработки 4 6 10
Завершение обработки 3 7 10
Завершение обработки 2 8 10
Срабатывание триггера hi_water 2 7 9
Завершение обработки 1 8 9
Срабатывание триггера hi_water 1 7 9
Завершение обработки 0 8 8
Срабатывание триггера hi_water 0 7 7

Обратите внимание, что с потоками ничего не происходит до тех пор, пока число блокированных потоков не превышает значение hi_water . Реализация здесь такова: как только поток завершает обработку, он проверяет число блокированных на данный момент потоков, и если их слишком много (то есть больше, чем предусмотрено параметром hi_water ), то «совершает самоубийство». Удобство использования параметров lo_water и hi_water в управляющих структурах состоит в том, что ими вы фактически задаете «эффективный диапазон» числа потоков, в пределах которого всегда доступно достаточное число потоков, и потоки без необходимости не создаются и не уничтожаются. В нашем случае, после выполнения действий, перечисленных в вышеупомянутых таблицах, мы имеем систему, которая способна обрабатывать до 4 запросов одновременно без необходимости в создании дополнительных потоков (7-4 = 3, что соответствует значению параметра lo_ water ).

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Роб Кёртен читать все книги автора по порядку

Роб Кёртен - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform отзывы


Отзывы читателей о книге Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform, автор: Роб Кёртен. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x