目录
- EventLoop就是对应的Reactor反应堆的组件!
- EPollPoller对应的是Demultiplex多路事件分发器的组件!
- Reactor调用Demultiplex相应的操作,对应muduo库上 就是EventLoop调用Poller、EPollPoller的相关操作。
- Channel通过调用EventLoop相应的方法在Poller事件分发器上添加、删除、修改事件!
服务器肯定有多个线程,一个线程执行一个EventLoop,所以我们会有很多个EventLoop,每个EventLoop都有很多Channel,自己Channel上的事件要在自己的EventLoop线程上去处理,为了控制这些逻辑,EventLoop在这里涉及到获取当前线程ID。
①: __thread 是一个存储类说明符,用于指示该变量是线程本地存储的,每个线程都有自己的变量副本,而不是共享同一个变量。它是一种线程级别的存储,与进程的其他线程隔离。
②:::syscall(SYS_gettid)全局函数获取当前线程id,static_cast<pid_t>强制类型转换
每个线程都有一个自己的t cachedTid.
我们看到是全局变量,所有线程共享的,加了thread (C++11是thread local,系统中是thread)意思是:虽然是全局变量,但是会在每一个线程存储一份拷贝,这个线程对这个变量的更改,别的线程是看不到的,在多线程中使用会方便一点。
③: 内联函数,在当前文件起作用,判断是否获取过当前线程id
CurrentThread.h
#pragma once
#include <unistd.h>
#include <sys/syscall.h>
namespace CurrentThread
{
//全局变量 __thread (C++11 是thread_local , 系统中是__thread)
//全局变量,但是会在每一个线程存储一份拷贝
//每个线程都有一个自己的t cachedTid。
extern __thread int t_cachedTid;
//Tid的访问是一个系统调用,总是从用空间切换到内核空间,比较浪费效率!
//第一次访问,就把当前线程的Tid存储起来,后边如果再访问就从缓存取
void cacheTid();
inline int tid()//内联函数,在当前文件起作用
{
if (__builtin_expect(t_cachedTid == 0, 0))//还没有获取过当前线程的id
{
cacheTid();
}
return t_cachedTid;
}
}
CurrentThread.cc
#include "CurrentThread.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));
}
}
}