如何判断pthread_self是否是进程中的主要(第一个)线程?

时间:2011-02-01 20:55:31

标签: c++ linux pthreads

背景:我正在研究许多程序使用的日志库 我为每个线程分配一个人类可读的名称,主线程应该是“main”,但我希望能够从库中检测到该状态,而不需要在每个main()函数的开头都有代码。

另请注意:不会始终首先从主线程输入库代码。

3 个答案:

答案 0 :(得分:13)

这有点可行,取决于您所使用的平台,但绝对不能以任何便携式和通用方式...

根据他们的pthread.h文件,Mac OS X似乎是唯一一个采用直接和文档化方法的人:

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

我还发现FreeBSD有一个定义pthread_main_np()的pthread_np.h头文件,所以这也适用于FreeBSD(至少8.1),OpenBSD(至少4.8)也有pthread_main_np()在pthread.h中定义。请注意,_np明确代表不可移植!

否则,我想到的唯一更“一般”的方法是将进程的PID与当前线程的TID进行比较,如果它们匹配,则该线程是主线程。 这并不一定适用于所有平台,它取决于你是否真的可以获得一个TID(例如你不能在OpenBSD中),如果你这样做,如果它与PID有任何关系,或者如果线程子系统有自己的会计,不一定相关。

我还发现有些平台将常量值作为主线程的TID给出,所以你可以检查一下。

我检查过的平台的简短摘要:

  • Linux:可能在这里,系统调用(SYS_gettid)== getpid()就是你想要的
  • FreeBSD:这里不可能,thr_self()似乎是随机的,与getpid无关()
  • OpenBSD:这里不可能,没有办法获得TID
  • NetBSD:可能在这里,_ lwp_self()总是为主线程返回1
  • Solaris:可能在这里,pthread_self()总是为主线程返回1

所以基本上你应该可以在Mac OS X,FreeBSD和OpenBSD上直接进行。

您可以在Linux上使用TID == PID方法。

您可以在NetBSD和Solaris上使用TID == 1方法。

我希望这会有所帮助,祝你有个美好的一天!

答案 1 :(得分:7)

从main()调用pthread_self()并记录结果。将未来对pthread_self()的调用与您存储的值进行比较,以了解您是否在主线程上。

答案 2 :(得分:0)

您可以利用某种共享名称资源,该资源允许生成的线程注册名称(可能是线程ID的地图名称)。然后,您的日志记录系统可以调用一个方法,该方法通过线程ID以线程安全的方式获取名称。

当线程死亡时,让它从映射中删除它的名称,以避免泄漏内存。

此方法应该允许命名所有线程,而不仅仅是main。