Вариации на тему

Хотя утилита идентификации потоков и является готовым продуктом, есть одна штука, которую я думал добавить в утилиту уже после сдачи ее заказчику. Только потому, что это отсутствовало в оригинальных требованиях, это никогда не было реализовано. Я говорю о возможности создания «именованных» потоков.

Рассмотрим стандартную POSIX функцию pthread_create():

int
pthread_create (pthread_t *thread,
const pthread_attr_t *attr,
void *(*func)(void *),
void *arg);

Если вы добавите всего один параметр, вы создадите POSIX-подобную функцию pthread_create_named():

int
pthread_create_named (pthread_t *thread,
const pthread_attr_t *attr,
void *(*func)(void *),
void *arg,
const char *name);
Последний параметр — имя, которое вы хотите присвоить создаваемому потоку.

Реализовать такую функцию труда не составит:

typedef struct pcn_s {
void *arg;
void *(*func) (void *);
const char *name;
} pcn_t;

static void *internal_worker (void *p);

int
pthread_create_named (pthread_t *thread,
const pthread_attr_t *attr,
void *(*func) (void *),
void *arg,
const char *name)
{
pcn_t *pcn;

pcn = (pcn_t *) malloc (sizeof (*pcn));
if (pcn == NULL) {
return (errno);
}
pcn -> arg = arg;
pcn -> name = name;
pcn -> func = func;
return (pthread_create (thread, attr, internal_worker, pcn));
}

static void *
internal_worker (void *p)
{
void *(*func) (void *);
void *arg;
pcn_t *pcn;

pcn = (pcn_t *) p;
tfp_mark (pcn -> name);
func = pcn -> func;
arg = pcn -> arg;
free (pcn);

return ((*func) (arg));
}
Все что мы сделали, это заставили pthread_create_named() вызвать внутреннюю рабочую функцию, которая выполняет маркировку потока и потом вызывает функцию потока. Заметьте, что к сожалению нам пришлось манипулировать с malloc() и free() — это потому, что pthread_create() принимает только одни аргумент, так что нам пришлось выделить массив для хранения всех параметров, которые нам нужно передать в рабочую функцию. Так как эти параметры необходимы для использования рабочей функции, они должны существовать на все время выполнения низкоуровневой функции потока, даже после разрушения стека pthread_create_named().