游戏服务器之被动连接线程池

来源:互联网 发布:淘宝拍照单反相机 编辑:程序博客网 时间: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();}



0 0
原创粉丝点击