ОК, кажется, это мой окончательный ответ. У нас есть 2 актуальные проблемы:
- Как получить более короткие уникальные идентификаторы для потока для регистрации.
- В любом случае нам нужно вывести реальный идентификатор pthread_t для потока (просто для ссылки на значения POSIX как минимум).
1. Печать идентификатора POSIX (pthread_t)
Вы можете просто рассматривать pthread_t как массив байтов с шестнадцатеричными цифрами, напечатанными для каждого байта. Таким образом, вы не ограничены каким-либо типом фиксированного размера. Единственная проблема - порядок байтов. Вам, вероятно, понравится, если порядок ваших напечатанных байтов такой же, как и для простого напечатанного «int». Вот пример для байтов с прямым порядком байтов, и только порядок должен быть возвращен (при определении?) Для байтов с прямым порядком байтов:
#include <pthread.h>
#include <stdio.h>
void print_thread_id(pthread_t id)
{
size_t i;
for (i = sizeof(i); i; --i)
printf("%02x", *(((unsigned char*) &id) + i - 1));
}
int main()
{
pthread_t id = pthread_self();
printf("%08x\n", id);
print_thread_id(id);
return 0;
}
2. Получите более короткую нить для печати ID
В любом из предложенных случаев вы должны перевести реальный идентификатор потока (posix) в индекс некоторой таблицы. Но есть 2 существенно разных подхода:
2,1. Отслеживать темы.
Вы можете отслеживать ID потоков всех существующих потоков в таблице (их вызовы pthread_create () должны быть обернуты) и иметь «перегруженную» функцию id, которая дает вам только индекс таблицы, а не идентификатор реального потока. Эта схема также очень полезна для любой внутренней отладки, связанной с отслеживанием ресурсов. Очевидным преимуществом является побочный эффект средства трассировки / отладки на уровне потоков с возможным будущим расширением. Недостатком является требование отслеживать создание / удаление любого потока.
Вот пример частичного псевдокода:
pthread_create_wrapper(...)
{
id = pthread_create(...)
add_thread(id);
}
pthread_destruction_wrapper()
{
/* Main problem is it should be called.
pthread_cleanup_*() calls are possible solution. */
remove_thread(pthread_self());
}
unsigned thread_id(pthread_t known_pthread_id)
{
return seatch_thread_index(known_pthread_id);
}
/* user code */
printf("04x", thread_id(pthread_self()));
2,2. Просто зарегистрируйте новый идентификатор темы.
Во время регистрации вызывайте pthread_self () и ищите внутреннюю таблицу, если она знает поток.
Если поток с таким идентификатором был создан, его индекс используется (или повторно используется из ранее созданного потока, на самом деле это не имеет значения, поскольку на тот же момент нет двух одинаковых идентификаторов). Если идентификатор потока еще не известен, создается новая запись, поэтому генерируется / используется новый индекс.
Преимущество - простота. Недостатком является отсутствие отслеживания создания / уничтожения потоков. Поэтому для отслеживания этого требуется некоторая внешняя механика.