仿muduo库实现高并发服务器----EventLoop与线程整合起来

目录

一、目的

二、含义

三、功能

四、成员变量

五、成员函数

六、Loopthread

1、目的

2、功能

3、成员变量

4、成员函数


一、目的

EventLoop模块与线程是一一对应的

EventLoop实例化的对象在构造的时候就会初始化_thread_id

而后边当运行一个操作的时候判断当前是否运行在eventloop模板对应的线程中,就是将线程ID与EventLoop模板中的thread_id进行一个比较,相同就表示在同一个线程,不同就表示当前运行线程并不是EventLoop线程

二、含义

EventLoop模板在实例化对象的时候必须在线程内部,EventLoop实例化对象时会设置自己的thread_id,如果我们先创建多个EventLoop对象,然后创建了多个线程,将各个线程的id,重新给Event Loop进行设置 存在问题,在构造EventLoop对象,到设置新的thread_id期间将是不可控的,因此我们必须先创建线程,然后再线程的入口函数中,去实例化EventLoop对象

所以我们构造一个新模块:LoopThread

三、功能

将EventLoop与thread整合到一起

思想:

1、创建线程

2、在线程中实例化EventLoop对象(可以向外部返回实例化的EventLoop)

四、成员变量

条件变量(用于实现_loop获取的同步关系避免线程创建,但是_loop还没有去实例化之前获取_loop*)

互斥锁

线程id

EventLoop指针变量,这个对象需要在线程内部实例化

五、成员函数

构造

创建线程,设定线程入口地址

线程入口地址

获取Loop指针

如果loop为NULL就一直阻塞

六、Loopthread

1、目的

对所有的LoopThread进行管理及分配

2、功能

1、线程数量课配置

注意事项:在服务器中,主从Reactor模型是主线程只负责新连接的获取,从属线程负责链接的事件监控及处理

因此当前的线程池有可能从属线程会数量为0,也就是实现单Reactor服务器,一个线程负责获取链接,也负责链接的处理

2、对所有的线程进行管理,其实就是管理0个或多个LoopThread对象

3、提供线程分配的功能

当主线程获取一个新连接,需要将新连接挂到从属线程上进行事件监控及处理

假设有0个从属线程,则直接分配给主线程的EventLoop进行处理,假设有多个从属线程则采用RR轮思想,进行线程的分配(将对应线程的EventLoop获取到,设置给对应的Connection)

3、成员变量

从属线程的数量

保存所有的LoopThreadPool

EventLoop运行在主线程从属线程数量为0,所有的操作都在baseLoop中进行

从属线程数量大于0则从_loops中进行EventLoop分配

下一个线程id

4、成员函数

构造

设置线程的数量

创建所有从属线程

下一个线程

cpp 复制代码
class LoopThread
{
private:
    std::mutex _mutex;
    std::condition_variable _cond;
    std::thread _thread;
    EventLoop *_loop;
    void ThreadEntry()
    {
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop = &loop;
            _cond.notify_all();
        }
        loop.Start();
    }

public:
    LoopThread() : _loop(NULL), _thread(std::thread(&LoopThread::ThreadEntry, this))
    {
    }
    EventLoop *GetLoop()
    {
        EventLoop *loop = NULL;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _cond.wait(lock, [&]()
                       { return _loop != NULL; });
            loop = _loop;
        }
        return loop;
    }
};
class LoopThreadPool
{
private:
    int _thread_cout;
    std::vector<LoopThread *> _threads;
    EventLoop *_baseloop;
    std::vector<EventLoop *> _loops;
    int _next_loop_idx;

public:
    LoopThreadPool(EventLoop *baseloop) : _thread_cout(0), _next_loop_idx(0), _baseloop(baseloop)
    {
    }
    void SetThreadCount(int cout)
    {
        _thread_cout = cout;
    }
    void Creat()
    {
        if (_thread_cout > 0)
        {
            _threads.resize(_thread_cout);
            _loops.resize(_thread_cout);
            for (int i = 0; i < _thread_cout; i++)
            {
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetLoop();
            }
            return;
        }
    }
    EventLoop *NextLoop()
    {
        if (_thread_cout == 0)
            return _baseloop;
        _next_loop_idx = (_next_loop_idx + 1) % _thread_cout;
        return _loops[_next_loop_idx];
    }
};
相关推荐
阿正呀32 分钟前
Redis怎样实现本地缓存的高效失效通知
jvm·数据库·python
九转成圣39 分钟前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio43 分钟前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
2501_901200531 小时前
mysql如何设置InnoDB引擎参数_优化innodb_buffer_pool
jvm·数据库·python
laowangpython1 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫1 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch1 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI1 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0011 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念2341 小时前
f5 shape分析
开发语言·javascript·ecmascript