Mac / iPhone:有没有办法在不使用Objective-C的情况下获取线程标识符?

时间:2009-10-08 21:27:43

标签: iphone macos pthreads

有没有办法在不使用Objective-C的NSThread的情况下获取当前正在运行的线程的任何类型的线程标识符。

我正在改进我们的自定义调试跟踪系统以正确处理多个线程。对于每行跟踪输出,我想打印一个线程ID或一个线程名称。线程以各种方式实例化,例如,使用NSOperationQueue和pthread函数。

我目前有以下两种选择,但我对其中任何一种都不满意。还有其他选择吗?

pthread_t选项

pthread_t似乎是特定平台_opaque_pthread_h的typedef。现在可以使用_opaque_pthread_h的字段,即使它是hack-y而且不可移植。它有一个类型为long的__sig字段,但对于我的进程的所有线程,它似乎具有相同的值。

NSThread选项

[NSThread name]需要NSAutoreleasePool,但我不希望这是一个要求,因为我们的大多数代码都是纯C ++,所以启动c ++函数会很好没有自动释放池包装。

4 个答案:

答案 0 :(得分:23)

我找到了一种足以获得跟踪输出的唯一标识符的方法。

pthread_mach_thread_np可用于获取线程标识符,iPhone上的unsigned int。

mach_port_t tid = pthread_mach_thread_np(pthread_self());

显然,这是在NSLog输出中使用的相同线程ID。

答案 1 :(得分:1)

请参阅pthread_getname_np

不幸的是,NSThread的名字目前还没有被推到那。 NSThread名称只是一个ivar,所以除非通过该方法,否则将无法获得它。您总是可以创建一个C函数来创建自动释放池并获取名称。那么你的C ++代码就不必编译成ObjC ++。

无论如何,

pthread_getname_np可能比NSThread的名字更有用。 gdb和Instruments不知道NSThread的名称,只知道pthread级别名称。

答案 2 :(得分:0)

使用Mach端口名称来标识线程的一个缺点是返回的名称是调用进程的本地名称。如果多个任务检索特定任务的线程(使用task_threads),则每个任务将检索特定线程的不同端口名称。

在OS X上,您可以使用thread_info检索唯一的64位标识符。这个标识符是全局的(对于给定的线程是相同的,无论哪个任务正在查询它)和唯一的(没有其他线程将在现在或将来使用相同的ID,直到重新启动之后 - 作为64位值,溢出不太可能。)

(请参阅XNU sourceXNU source。)

使用以下代码中的代码检索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 source。)

两个注释:

  1. THREAD_IDENTIFIER_INFO没有文档,或者至少没有我能找到的文档。所以我认为,严格来说,这使得它没有文件记录。但它位于THREAD_BASIC_INFO旁边的公共标题中, 记录了 - 所以我假设这只是一个疏忽。它不像任何这些东西的文档特别好。)

  2. 我不知道iOS上的情况如何,但THREAD_IDENTIFIER_INFOpthread_mach_thread_np似乎都在标题中可用,因此值得一试。

答案 3 :(得分:0)

我很欣赏这是一个很老的问题。

要获得我使用的 macOS 的 Thread ID 中报告的相同 Console.app

uint64_t tid;
pthread_threadid_np(NULL, &tid);
printf("%#08x\nr", (unsigned int) tid);

macOS 上 Console.app 的屏幕截图。

enter image description here