Windows NT有一个很好的名为GetCurrentThreadId
的函数,它的名字就是它的意思。它的实现非常快,因为它只是从NT内核创建线程期间从线程本地存储中读取一个变量。我想在Linux中实现它,但我遇到了麻烦。
我最初的实施是:
typedef pid_t ThreadID;
ThreadID GetCurrentThreadId(void)
{
static __thread ThreadID t_cachedID = (ThreadID) -1;
if (__builtin_expect(t_cachedID == (ThreadID) -1, 0))
{
t_cachedID = (ThreadID) syscall(__NR_gettid);
}
return t_cachedID;
}
问题是fork
。在使用fork
的程序中,t_cachedID
变得陈旧 - 新的子进程的主线程有一个调用fork
的线程的线程本地存储的副本,并且t_cachedID
不再正确。
解决方案应该是pthread_atfork
,以便将新子进程中的t_cachedID
值更改为-1,但这是Pthreads API的标准,它是&#39}设计拙劣的。如果您是使用dlclose
卸载的DLL,pthread_atfork
不知道这一点,并且仍会尝试在fork
和kaboom上调用您的函数。糟糕的设计决定#1。也没有用于删除回调函数的API。糟糕的设计决定#2。
有一个模糊记录的glibc函数名为__register_atfork
似乎旨在解决此问题,但它需要一个DLL句柄,而不是提供一种方法来删除*_atfork
处理程序。在尝试解决POSIX糟糕的设计决策时,glibc做出了糟糕的设计决策#1。
如何获得自己的DLL句柄?在Linux中,似乎dlopen
每次有人在DLL / .so文件上调用void *
时返回不同的dlopen
句柄,而不仅仅是维护引用计数......?它不像Windows,其中DLL句柄等于节映射的基地址。除非在Linux中有一些简单的方法来获取自己的DLL句柄,否则这将导致设计决策#2不佳。
有没有更好,更合适的方法呢?
答案 0 :(得分:4)
嗯,实际上posix已经contains function返回线程ID:
pthread_self() //thanks to alk
旧答案: <击> 撞击>
<击>int thr_self()
击> <击> 撞击>