Mac/iPhone: есть ли способ получить идентификатор потока без использования Objective-C?
Есть ли способ получить какой-либо идентификатор потока текущего текущего потока, не прибегая к Objective-C NSThread.
Я улучшаю нашу систему отслеживания отладки, чтобы правильно обрабатывать несколько потоков. Для каждой строки вывода трассировки я хотел бы напечатать идентификатор потока или имя потока. Темы создаются различными способами, например. используются функции NSOperationQueue и pthread.
В настоящее время у меня есть следующие две альтернативы, но я не удовлетворен ни одним из них. Есть ли другие варианты?
опция pthread_t
pthread_t
кажется типичным для конкретной платформы _opaque_pthread_h
. Было бы нормально использовать поля _opaque_pthread_h
пока, даже если он взломан и не переносится. Он имеет тип __sig
типа long, но, похоже, имеет одинаковое значение для всех потоков моего процесса.
Вариант NSThread
[NSThread name]
требует, чтобы NSAutoreleasePool
был на месте, но я не хочу, чтобы это было требованием, поскольку большая часть нашего кода является чистым С++, поэтому было бы неплохо запустить функцию С++ без обертки пула автозаполнения,
Ответы
Ответ 1
Я нашел один способ, который достаточно, чтобы получить какой-то уникальный идентификатор для вывода трассировки.
pthread_mach_thread_np
можно использовать для получения идентификатора потока, неподписанного int на iPhone.
mach_port_t tid = pthread_mach_thread_np(pthread_self());
По-видимому, это тот же самый идентификатор потока, который используется в выходе NSLog.
Ответ 2
См. pthread_getname_np
.
К сожалению, имя NSThread в настоящее время не подталкивается к этому. Имя NSThread - это просто ivar, поэтому не будет никакого способа получить его, кроме как через метод. Вы всегда можете создать функцию C, которая создает пул автозапуска и получает имя. Ваш код на С++ не должен быть скомпилирован как ObjС++.
pthread_getname_np
, вероятно, немного полезнее, чем имя NSThread прямо сейчас. gdb и Instruments не знают о имени NSThread, только имя уровня pthread.
Ответ 3
Одним из недостатков использования имени порта Mach для идентификации потока является то, что возвращенное имя является локальным для вызывающего процесса. Если несколько задач извлекают конкретные потоки задач (используя task_threads
), каждая задача будет извлекать другое имя порта для определенного потока.
В OS X вы можете получить уникальный 64-битный идентификатор, используя thread_info
. Этот идентификатор является глобальным (он одинаковый для данного потока, независимо от того, какая задача запрашивает его) и уникальная (ни один другой поток никогда не будет иметь тот же идентификатор, теперь или в будущем, до тех пор, пока после перезагрузки, конечно, - как 64 -бит значение, переполнение маловероятно).
(см. источник XNU, источник XNU.)
Получить этот идентификатор для pthread, используя код в этих строках:
uint64_t GetThreadID(pthread_t thread) {
mach_port_name_t port=pthread_mach_thread_np(thread);
thread_identifier_info_data_t info;
mach_msg_type_number_t info_count=THREAD_IDENTIFIER_INFO_COUNT;
kern_return_t kr=thread_info(thread,
THREAD_IDENTIFIER_INFO,
(thread_info_t)&info,
&info_count);
if(kr!=KERN_SUCCESS) {
/* you can get a description of the error by calling
* mach_error_string(kr)
*/
return 0;
} else {
return info.thread_id;
}
}
(Смотрите источник XNU.)
Две заметки:
-
Нет документации для THREAD_IDENTIFIER_INFO
или, по крайней мере, нет, которую я смог найти. Поэтому, я полагаю, строго говоря, это делает его недокументированным. Но это в публичных заголовках, рядом с THREAD_BASIC_INFO
, что задокументировано - поэтому я предполагаю, что это просто недосмотр. Это не похоже на документацию для любого из этого материала, особенно замечательно.)
-
Я не знаю, что такое ситуация в iOS, но THREAD_IDENTIFIER_INFO
и pthread_mach_thread_np
оба кажутся доступными в заголовках, поэтому стоит попробовать.