void (*context_free)(THREAD_POOL_PARAM_T* ctp);
pthread_attr_t* attr;
unsigned short lo_water;
unsigned short increment;
unsigned short hi_water;
unsigned short maximum;
unsigned reserved[8];
} thread_pool_attr_t;
Дескриптор создаваемого пула потоков handle
dispatch_t:#ifndef THREAD_POOL_HANDLE_T
#define THREAD_POOL_HANDLE_T dispatch_t
#endif
Атрибуты потоков, которые будут работать в составе пула, определяются полем attr
pthread_attr_t (эту структуру мы детально рассматривали ранее при обсуждении создания единичных потоков).Численные параметры пула определяют:
lo_water
lo_water, создается дополнительно increment потоков, которые переводятся в блокированное состояние.hi_water
hi_water, то этот поток уничтожается.maximum
lo_water, но общее число потоков уже достигнет maximum, то новые потоки для пула создаваться не будут.Функциональные параметры пула определяют:
context_alloc()
context_free() — функции создания и уничтожения контекста потока, которые вызываются при создании и уничтожении каждого потока пула. Функция создания контекста потока ответственна за индивидуальные настройки создаваемого потока. Она возвращает «указатель на контекст» типа THREAD_POOL_PARAM_T. Однако системе такой тип неизвестен:#ifndef THREAD_POOL_PARAM_T
#define THREAD_POOL_PARAM_T void
#endif
В качестве контекста может использоваться любой пользовательский тип, и он будет передаваться последовательно в качестве параметра (ctp
block_func()
context_alloc() или после очередного этапа выполнения потоком функции обработчика handler_func(). Функция блокирования получает и возвращает далее обработчику (возможно, после модификации) структуру контекста (в приведенном выше примере контекстом является int — значение присоединенного TCP-сокета).handler_func()
block_func(), при этом функция-обработчик handler_func() получит параметр контекста, возвращенный block_func().В текущей реализации handler_func()
unblock_func() зарезервирована для дальнейших расширений, и вместо ее адреса следует устанавливать NULL.2. После создания атрибутной записи пула, определяющей всю функциональность его дальнейшего поведения, можно приступать к непосредственному созданию пула потоков:
thread_pool_t* thread_pool_create(
thread_pool_attr_t* attr, unsigned flags);
где attr
flags
thread_pool_start(). В документации описано два возможных значения флага: • POOL_FLAG_EXIT_SELF
thread_pool_start() (часто это главный поток приложения), завершается; • POOL_FLAG_USE_SELF
thread_pool_start(), включается в пул в качестве одного из его потоков.И в том и в другом случае в типовом фрагменте (как и в показанном выше примере):
thread_pool_start(tpp);