游戏服务器之被动连接线程池
来源:互联网 发布:淘宝拍照单反相机 编辑:程序博客网 时间:2024/05/01 21:54
本文内容是游戏服务器之被动连接线程池。顾名思义,被动连接线程池处理的是被动连接的会话的状态管理和数据收发。
设计上:
每个服务器对象有个接收连接线程池, 线程类型包括:
验证线程、同步线程、网络接收发送线程、回收线程。
会话正常流程步骤(正常状态切换流程):
(1)程序主线程接收连接(监听连接)
(2)验证线程(检查验证超时、验证发来消息的服务器id和服务器ip(服务器之间,依靠中心服务器发来的依赖服务器列表)、验证账号和临时id和账号(客户端登陆和重登陆))
(3)同步线程(网关发消息删除中心服务器登陆会话,中心服务器读数据库检查其他服务器连接的合法性、发送测试消息到对端)
(4)网络接收发送线程
(5)回收线程(回收连接)
本文内容:
1、被动连接线程池初始化
初始化是在进程主线程的服务器对象(具体服务器类对象)的初始化函数里。
线程类型包括:回收线程、验证线程、同步线程、网络接收发送线程(网络接收发送线程也是根据配置有多个)。
线程池初始化
创建线程:回收线程 1 个,验证线程 2个,同步线程1个,业务网络数据接收发送线程 随不同服务器而变化(网关4个,场景1个等)bool tcp_session_pool::init(){//创建回收线程if(!recycleThreads.init(1,1,"recycle_thread",this)){g_log->debug("recycle_thread线程启动失败");return false;}//创建初始化验证线程if(!verifyThreads.init(1,2,"verify_thread",this))//检查验证超时、中心服务器的服务器配置验证(读数据库){g_log->debug("verify_thread线程启动失败");return false;}//创建初始化同步线程if(!syncThreads.init(1,1,"sync_thread",this)){g_log->debug("sync_thread线程启动失败");return false;}//创建初始业务网络数据接收发送线程(这里的网络接收发送线程只是处理网络接收和发送的线程)int maxThreadCount = (maxConns + main_service_thread::getMaxSize() - 1)/main_service_thread::getMaxSize();g_log->debug("线程最大连接数%d,每线程连接数%d,线程个数%d",maxConns,main_service_thread::getMaxSize(),maxThreadCount);if(!okayThreads.init(1,maxThreadCount,"main_service_thread",this)){g_log->debug("main_service_thread线程启动失败");return false;}return true;}
2、被动连接池的会话管理
连接的状态处理是由线程池的那些状态管理线程来处理的,连接的状态会进行转换,把连接对象交给其他线程来管理。
(1)未使用会话到验证线程
bool tcp_session_pool::addVerify(tcp_session *task){verify_thread *pThread = verifyThreads.getOne();if(pThread){/** cjy*state_notuse -> state_verfy * 先设置状态再添加容器,* 否则会导致一个task同时在两个线程中的危险情况*/task->getNextState();pThread->add(task);}else{g_log->error("没有找到验证线程添加任务");}return true;}
(2)验证会话到同步线程
void tcp_session_pool::addSync(tcp_session *task){sync_thread *pThread = syncThreads.getOne();if(pThread){// state_verify-> state_sync/** cjy* 先设置状态再添加容器*/task->getNextState();pThread->add(task);}else{g_log->error("没有找到回收线程添加任务");}}
(2)同步会话到网络收发线程
bool tcp_session_pool::addOkay(tcp_session *task){main_service_thread *pThread = okayThreads.getOne();if (pThread){// state_sync -> state_okay/** cjy* 先设置状态再添加容器,*/task->getNextState();pThread->add(task);return true;}g_log->fatal("没有找到主线程添加任务");//没有找到线程来处理这个连接,需要回收关闭连接return false;}
(3)会话到回收线程
void tcp_session_pool::addRecycle(tcp_session *task){recycle_thread *pThread = recycleThreads.getOne();if(pThread){pThread->add(task);}else{g_log->error("没有找到回收线程添加任务");}}
3、网络数据收发
业务网络收发线程的循环部分,处理网络数据的接收和发送。
设计上:
(1)先检查所有连接是否处于正常状态。
(2)网络的处理是读优先的,有读才检查写,写的检查是一段时间检查一次(目前是50ms)。
实现上通过两个epoll描述符来处理。
第一个epoll描述符监听所有连接的读事件,并处理网络数据的接收。
第二个epoll描述符监听所有连接的写事件(顺带会检查读事件),并处理网络数据的发送(顺带会处理有读事件的连接的接收)。
详细查看
http://blog.csdn.net/chenjiayi_yun/article/details/31765803
4、服务器关闭销毁连接池线程和epoll句柄资源
server_base::~server_base(){if (taskPool)//回收连接池,关闭连接管理和收发的线程{taskPool->final();SAFE_DELETE(taskPool);}//关闭epoll句柄TEMP_FAILURE_RETRY(::close(epoll_handler));if (-1 != sock_handler) {::shutdown(sock_handler, SHUT_RD);//<span style="color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; text-indent: 28px;">关闭sockfd上的读功能,此选项将不允许sockfd进行读操作</span>TEMP_FAILURE_RETRY(::close(sock_handler));sock_handler = -1;}}
连接池删除时需要关闭所有这些线程
void tcp_session_pool::final(){g_log->debug("%s", __PRETTY_FUNCTION__);verifyThreads.final();syncThreads.final();okayThreads.final();recycleThreads.final();}
- 游戏服务器之被动连接线程池
- 游戏服务器之被动连接线程池
- 游戏服务器之服务器之间的被动连接
- 游戏服务器之主动连接线程池
- 游戏服务器之线程池管理器
- 游戏服务器之线程池调度策略
- 游戏服务器之mysql句柄连接池
- 游戏服务器之mysql句柄连接池
- 游戏服务器之mysql句柄连接池
- 游戏服务器之mysql句柄连接池
- 游戏服务器之线程封装
- 游戏服务器之连接接收
- 游戏服务器之python短连接服务器(登录服务器)
- 游戏服务器之服务器之间的主动连接
- 游戏服务器之长连接服务器(python)(1)
- 游戏服务器之长连接服务器(python)(2)
- 服务器连接永远都应设计为“被动”关闭?
- 游戏服务器之跨平台线程的实现
- Linux系统服务 5 ---- Vsftpd匿名用户不能下载原因分析及解决
- 开发Qt Plugin 3
- Qt for Android 编译纯C工程
- QT 多线程信号与槽(三)
- 关于Windows下ShellCode编写的一点思考
- 游戏服务器之被动连接线程池
- ZXing简介与核心库编译
- 字符数组名可以相互赋值吗
- 影像匀色及影像匀色软件
- 全新的开始
- 深度学习的资料和代码整理
- At least one JAR was scanned for TLDs yet contained no TLDs.&Multiple bindings were found
- Eclipse各主要版本的区别
- 第一天开通我的博客