2011-02-01 85 views
7

背景:我正在处理许多程序使用的日志记录库。
我为每个线程分配一个人类可读的名称,主线程应该获得“主”,但我希望能够从库中检测到该状态,而不需要每个主开始时的代码( )功能。如何判断pthread_self是否是过程中的主要(第一个)线程?

另请注意:库代码并不总是首先从主线程输入。

+0

你如何获得其他人类可读的名字? – Potatoswatter 2011-02-01 21:27:31

+0

更具体地说,`main`不符合的模式是什么? – Potatoswatter 2011-02-01 21:51:39

+0

系统中的大部分线程都是以少数几种方式启动的。这里有一些常见的代码可以依赖一个虚拟的std :: string name()函数。主线程虽然不同。 – 2011-02-01 22:08:41

回答

11

这是有点可行的,这取决于你的平台上,但绝对不是在任何便携和通用的方式...

的Mac OS X似乎是唯一一个直接和记录方法,根据它们的pthread.h文件:

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

我还发现,FreeBSD有pthread_np.h头限定pthread_main_np(),所以这应该(至少8.1)在FreeBSD工作太,和OpenBSD(4.8至少)在pthread.h中也定义了pthread_main_np()。请注意,_np明确表示不可移植!

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

我还发现一些平台会给主线程返回TID的常量值,所以你可以检查这些值。

平台的简要总结我检查:

  • Linux的:可能在这里,系统调用(SYS_gettid)== GETPID()是你想要什么
  • FreeBSD的:不可能在这里,thr_self ()似乎随机的,没有关系GETPID()
  • OpenBSD的:不可能在这里,有没有办法让一个TID
  • NetBSD的:可能在这里,_lwp_self()总是第m返回1艾因螺纹
  • 的Solaris:可能在这里,pthread_self()总是在主线程

返回1所以基本上你应该能够直接做在Mac OS X,FreeBSD和OpenBSD系统。

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

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

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

7

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

0

您可以利用某种共享名称资源,该资源允许产生线程来注册一个名称(可能是线程ID的映射名称)。然后,您的日志记录系统可以将一个调用放入一个方法中,该方法通过线程标识以线程安全的方式获取名称。

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

该方法应该允许所有线程被命名,而不仅仅是主要的。

相关问题