在Linux中实现快速“GetCurrentThreadId”

时间:2014-06-08 07:26:15

标签: linux multithreading pthreads posix

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不佳。

有没有更好,更合适的方法呢?

1 个答案:

答案 0 :(得分:4)

嗯,实际上posix已经contains function返回线程ID:

 pthread_self() //thanks to alk 

旧答案: <击>

<击>
int thr_self()

<击>