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 оба кажутся доступными в заголовках, поэтому стоит попробовать.