exit(EXIT_SUCCESS);

управление никогда не дойдет до выполнения exit(). Но существует еще третье допустимое значение, прямо не указанное в документации, но мельком упоминаемое в других местах документации:

 • 0 — после старта пула поток, вызвавший thread_pool_start(), продолжает свое естественное выполнение.

Например, некоторый фрагмент кода мог бы выглядеть так:

thread_pool_attr_t att; // ...

thread_pool_t *tpp = thread_pool_create(&attr, 0);

thread_pool_start(tpp);

while (true) {

 // выполнять некоторую отличную от пула работу

}

exit(EXIT_SUCCESS);

Как уже понятно из описаний, thread_pool_create() возвращает указатель на управляющую структуру пула потоков, которая позже будет передана thread_pool_start(). Если создание пула завершилось неудачей, то результатом выполнения будет NULL, а в errno будет установлен код ошибки (документацией предусмотрен только один код ошибки: ENOMEM — недостаточно памяти для размещения структур данных).

Примечание

Управляющая структура пула потоков описана так:

typedef struct _thread_pool thread_pool_t;

struct _thread_pool {

 thread_pool_attr_t pool_attr;

 unsigned created;

 unsigned waiting;

 unsigned flags;

 unsigned reserved[3];

};

3. Последний шаг в процедуре запуска пула потоков:

int thread_pool_start(void* pool);

где pool — это указатель, возвращаемый thread_pool_create().[40]

При успешном завершении (которого почти никогда не происходит, за исключением значения флага 0; об этом см. выше) функция возвращает EOK, в противном случае (что происходит гораздо чаще) — значение -1.

4. Другие, относящиеся к библиотеке динамического пула потоков функции, которые целесообразно посмотреть в документации QNX (но которые в силу различных обстоятельств используются гораздо реже):

int thread_pool_destroy(thread_pool_t* pool);

int thread_pool_control(thread_pool_t* pool, thread_pool_attr_t* attr,

 _Uint16t lower, _Uint16t upper, unsigned flags);

int thread_pool_limits(thread_pool_t* pool,

 int lowater, int hiwater, int maximum, int increment, unsigned flags);

<p>Менеджеры ресурсов</p>

QNX вводит технику программирования, которая единообразно проходит сквозь всю систему.[41] Идея техники менеджеров ресурсов столь же проста, сколь и остроумна:

• Вся система построена на тщательно проработанной в теории (и редко используемой при построении реальных ОС) концепции - коммутации сообщений. Ядро (точнее «микроядро») операционной системы при таком подходе выступает в качестве компактного коммутатора сообщений между взаимодействующими программными компонентами. При этом взаимодействующие компоненты выступают в качестве клиента, запрашивающего услугу (ресурс), и сервера, обеспечивающего эту услугу (обслуживающего ресурс).

• Большинство системных вызовов API (в том числе все «привычные» POSIX-вызовы: open(), read(), write(), seek(), close()…) реально посылаются обслуживающему данный ресурс сервису (например, в файловую систему типа FAT32 — fs-dos) в виде сообщений уровня микроядра. Код сообщения при этом определяет тип операции (например, open()), а последующее тело сообщения — конкретные параметры запроса, зависящие от типа операции (параметры запроса пакуются в тело сообщения).

• Раз эта схема столь универсальна, единообразна и не зависит от конкретной природы ресурса, на котором обеспечивается обслуживание, то разработчики QNX предоставляют некоторый шаблон сервера, в котором на месте обработчиков стандартных POSIX-запросов находятся пустые программные заглушки. Этот шаблон и служит базовым элементом построения разнообразных серверов услуг, называемых при выполнении в такой технике «менеджерами ресурса».

• При запуске программа менеджера ресурса регистрирует свое имя (точнее имя управляемого ею ресурса) в пространстве имен файловой системы QNX (обычно в каталоге /dev, но это может быть любое место файловой системы). Теперь можно обращаться с запросами к данному менеджеру так же, как и к любому реальному файлу в файловой системе.

Перейти на страницу:

Все книги серии High tech

Нет соединения с сервером, попробуйте зайти чуть позже