获取线程tid代码

126 阅读1分钟

EventLoop对应Reactor反应堆的组件,EPollPoller对应的是Demultiplex事件分发器组件,依赖一个IO复用Epoll来实现的,也就是说Reactor来调用事件分发器相应的操作,对应muduo库上就是EventLoop调用Poller的操作。Channel通过调用EventLoop相应的方法,最终还是EventLoop调用Poller相应的方法。

我们的服务器程序不一定就只有1个eventloop,我们可能有很多的eventloop,每个eventloop都有很多channel,自己channel上的事件要在自己的eventloop线程上去处理,eventloop在这里涉及到获取当前线程的ID

ps -ef | grep mysqld获取进程id

image.png

top -HP 961获取线程id

image.png

image.png

我们看到是全局变量, 所有线程共享的,加了__thread,或者是C++11的thread_local来定义的话,就是:虽然是全局变量,但是会在每一个线程存储一份拷贝,这个线程对这个变量的更改,别的线程是看不到的
因为tid的访问是系统调用,总是从用户空间切到内核空间的话比较浪费效率,所以第一次访问,就把当前线程的Tid存储起来,后边如果再访问就从缓存取。

image.png

image.png 其实就是用了一个系统调用获取当前线程的ID值。

CurrentThread.h

#pragma once

namespace CurrentThread
{
    extern __thread int t_cachedTid;

    void cacheTid();

    inline int tid() //内联函数,在当前文件起作用 
    {
        if(__builtin_expect(t_cachedTid == 0, 0)) //还没有获取过当前线程的id 
        {
            cacheTid();
        }
        return t_cachedTid;
    }
}

CurrentThread.cc

#include "CurrentThread.h"

#include <unistd.h>
#include <sys/syscall.h>

namespace CurrentThread
{
    __thread int t_cachedTid = 0;

    void cacheTid()
    {
        if(t_cachedTid == 0)
        {
            //通过linux系统调用,获取当前线程的tid值
            t_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid));
        }
    }
}