how can I tell if pthread_self is the main (first) thread in the process?

前端 未结 3 1891
猫巷女王i
猫巷女王i 2021-01-11 16:59

background: I\'m working on a logging library that is used by many programs.
I\'m assigning a human-readable name for each thread, the main thread should get \"main\", b

相关标签:
3条回答
  • 2021-01-11 17:19

    Call pthread_self() from main() and record the result. Compare future calls to pthread_self() to your stored value to know if you're on the main thread.

    0 讨论(0)
  • 2021-01-11 17:24

    This is kinda doable, depending on the platform you're on, but absolutely not in any portable and generic way...

    Mac OS X seems to be the only one with a direct and documented approach, according to their pthread.h file:

    /* returns non-zero if the current thread is the main thread */
    int pthread_main_np(void);
    

    I also found that FreeBSD has a pthread_np.h header that defines pthread_main_np(), so this should work on FreeBSD too (8.1 at least), and OpenBSD (4.8 at least) has pthread_main_np() defined in pthread.h too. Note that _np explicitly stands for non-portable!

    Otherwise, the only more "general" approach that comes to mind is comparing the PID of the process to the TID of the current thread, if they match, that thread is main. This does not necessarily work on all platforms, it depends on if you can actually get a TID at all (you can't in OpenBSD for example), and if you do, if it has any relation to the PID at all or if the threading subsystem has its own accounting that doesn't necessarily relate.

    I also found that some platforms give back constant values as TID for the main thread, so you can just check for those.

    A brief summary of platforms I've checked:

    • Linux: possible here, syscall(SYS_gettid) == getpid() is what you want
    • FreeBSD: not possible here, thr_self() seems random and without relation to getpid()
    • OpenBSD: not possible here, there is no way to get a TID
    • NetBSD: possible here, _lwp_self() always returns 1 for the main thread
    • Solaris: possible here, pthread_self() always returns 1 for the main thread

    So basically you should be able to do it directly on Mac OS X, FreeBSD and OpenBSD.

    You can use the TID == PID approach on Linux.

    You can use the TID == 1 approach on NetBSD and Solaris.

    I hope this helps, have a good day!

    0 讨论(0)
  • 2021-01-11 17:26

    You can utilize some kind of shared name resource that allows threads that spawn to register a name (perhaps a map of thread id to name). Your logging system can then place a call into a method that gets the name via the thread ID in a thread-safe manner.

    When the thread dies, have it remove it's name from the mapping to avoid leaking memory.

    This method should allow all threads to be named, not just main.

    0 讨论(0)
提交回复
热议问题