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