Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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", but I'd like to be able to detect that state from within the library without requiring code at the beginning of each main() function.

Also note: The library code will not always be entered first from the main thread.

like image 207
Mark Borgerding Avatar asked Feb 01 '11 20:02

Mark Borgerding


1 Answers

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!

like image 70
llongi Avatar answered Oct 11 '22 12:10

llongi