开发者

Mac/iPhone: Is there a way to get a thread identifier without using Objective-C?

Is there a way to get any kind of thread identifier of the currently running thread without resorting to Objective-C's NSThread.

I'm improving our custom debug tracing system to handle multiple threads properly. For each line of trace output, I'd like to print a thread id or a thread name. Threads are instantiated in various ways, e开发者_Go百科.g. both NSOperationQueue and pthread functions are used.

I've currently a following two alternatives, but I'm not satisfied with either of them. Are there any other options?

pthread_t option

pthread_t seems to be a typedef of a platform specific _opaque_pthread_h. It would be ok to use fields of _opaque_pthread_h for now, even if it's hack-y and not portable. It has a __sig field of type long, but that seems to have a same value for all threads of my process.

NSThread option

[NSThread name] requires NSAutoreleasePool to be in place, but I don't want that to be a requirement as most of our code is pure C++, so it would be nice to just to launch c++ function without autorelease pool wrapping.


I found a one way that is enough to get some kind of unique identifier for trace output.

pthread_mach_thread_np can be used to get a thread identifier, an unsigned int on iPhone.

mach_port_t tid = pthread_mach_thread_np(pthread_self());

Apparently this is a same thread id that is used in NSLog output.


I appreciate this is a pretty old question.

To get the same Thread ID that is reported in macOS's Console.app I used:

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

A screenshot from Console.app on macOS.

Mac/iPhone: Is there a way to get a thread identifier without using Objective-C?


See pthread_getname_np.

Unfortunately NSThread's name is not currently pushed down to that. The NSThread name is just an ivar, so there will be no way to get at it except through the method. You could always make a C function that makes the autorelease pool and gets the name. Your C++ code then doesn't have to be compiled as ObjC++.

pthread_getname_np is probably a bit more useful than NSThread's name right now anyway. gdb and Instruments don't know about NSThread's name, only the pthread level name.


One disadvantage of using a Mach port name to identify a thread is that the name returned is local to the calling process. If several tasks retrieve a particular task's threads (using task_threads), each task will retrieve a different port name for a particular thread.

On OS X, you can retrieve a unique 64-bit identifier using thread_info. This identifier is global (it is the same for a given thread, no matter which task is querying it) and unique (no other thread will ever have the same ID, now or in the future, until after reboot of course - as a 64-bit value, overflow is unlikely).

(See XNU source, XNU source.)

Retrieve this identifier for a pthread using code along these lines:

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(port,
                                 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;
    }
}

(See XNU source.)

Two notes:

  1. There's no documentation for THREAD_IDENTIFIER_INFO, or at least none that I've been able to find. So I suppose, strictly speaking, that makes it undocumented. But it's in the public headers, right next to THREAD_BASIC_INFO, which is documented - so I'm assuming this is simply an oversight. It's not like the documentation for any of this stuff is particularly great.)

  2. I don't know what the situation is on iOS, but THREAD_IDENTIFIER_INFO and pthread_mach_thread_np both appear to be available in the headers, so it could be worth a try.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜