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

Кёртен Роб

Шрифт:

 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
  • Читать дальше
  • 1
  • ...
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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