【问题标题】:how can I tell if pthread_self is the main (first) thread in the process?如何判断 pthread_self 是否是进程中的主(第一个)线程?
【发布时间】:2011-06-19 13:33:07
【问题描述】:

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

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

【问题讨论】:

  • 如何获得其他人类可读的名称?
  • 更具体地说,main 不符合的模式是什么?
  • 系统中的大多数线程仅以少数几种方式启动。那里有可以依赖虚拟 std::string name() 函数的通用代码。但是主线程是不同的。
  • 如果您可以在每个其他线程启动时为其注册一个名称,那么如果没有注册名称,也许您可​​以假设一个线程是main

标签: c++ linux pthreads


【解决方案1】:

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

【讨论】:

  • 我已经编辑了我的问题,以澄清这个库被许多程序使用。向每一个都添加新代码是不可取的。
  • 你可以使用__attribute__((constructor))
【解决方案2】:

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

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

这个方法应该允许命名所有线程,而不仅仅是主线程。

【讨论】:

  • 我已经掌握了这一切。这无助于自动确定哪个线程是主线程。
【解决方案3】:

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

根据他们的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.h 中也定义了 pthread_main_np() .请注意,_np 明确表示不可移植!

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

我还发现一些平台会返回常量值作为主线程的 TID,因此您可以检查这些值。

我检查过的平台的简要总结:

  • Linux:这里可以,syscall(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 方法。

希望对你有帮助,祝你有个美好的一天!

【讨论】:

  • MacOSX 在 *BSD 中有着深厚的根基,这在某种程度上解释了它对 pthread_main_np() 的使用从何而来。它也是所有 *BSD 上的一个完整记录的界面(有一个联机帮助页)。 Solaris 与thr_main() 等效,您可以在此处简单地使用#define pthread_main_np thr_main。比 TID == 1 技巧更好地使用它。
  • 这可能不用多说,但如果你也打算为iOS编写,pthread_main_np()函数也是支持的。
猜你喜欢
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
  • 2020-07-21
  • 2013-01-14
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多