Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何判断pthread_self是否是进程中的主(第一个)线程?_C++_Linux_Pthreads - Fatal编程技术网

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

C++ 如何判断pthread_self是否是进程中的主(第一个)线程?,c++,linux,pthreads,C++,Linux,Pthreads,背景:我正在开发一个被许多程序使用的日志库。 我为每个线程分配了一个人类可读的名称,主线程应该得到“main”,但我希望能够从库中检测到该状态,而不需要在每个main()函数的开头编写代码 另请注意:库代码并不总是首先从主线程输入。从main()调用pthread_self()并记录结果。将将来对pthread_self()的调用与存储的值进行比较,以了解您是否在主线程上。您可以利用某种共享名称资源,允许生成的线程注册名称(可能是线程id到名称的映射)。然后,您的日志系统可以调用一个方法,该方法

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


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

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

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

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


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

这是可行的,取决于您所在的平台,但绝对不能以任何可移植和通用的方式命名

根据他们的文件,Mac OS X似乎是唯一一个有直接记录的方法:

我还发现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\u getId)==getpid()就是您想要的
  • FreeBSD:这里不可能,thr_self()看起来是随机的,与getpid()无关
  • OpenBSD:这里不可能,没有办法获得TID
  • NetBSD:这里可能,\u lwp\u self()始终为主线程返回1
  • Solaris:此处可能,pthread_self()始终为主线程返回1
所以基本上你应该能够直接在MacOSX、FreeBSD和OpenBSD上完成

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

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


我希望这有帮助,祝你有一个愉快的一天

这一切我都已经准备好了。这无助于自动确定哪个线程是主线程。我编辑了我的问题,以澄清这个库被许多程序使用。向每一个添加新代码都是不可取的。您可以使用
\uuuuu属性(构造函数))
。如何获得其他人类可读的名称?更具体地说,
main
无法遵循的模式是什么?系统中的大多数线程仅以几种方式启动。这里有一些公共代码可以依赖于虚拟std::string name()函数。但是主线程是不同的。如果您可以在其他线程启动时为其注册一个名称,那么如果没有注册名称,那么您可能可以假设线程是
main
?MacOSX在*BSD中有很强的根,这在某种程度上解释了
pthread\u main\u np()
的用法。在所有的BSD上,它也是一个完全文档化的界面(有一个手册页)。Solaris具有与
thr\u main()
等效的功能,您可以在那里简单地定义pthread\u main\u np thr\u main。使用它比使用
TID==1
技巧更好。这可能不用说,但是如果您也计划为iOS编写,pthread\u main\u np()函数也受支持。
/* returns non-zero if the current thread is the main thread */
int pthread_main_np(void);