从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)

(1)学习方法
学习解决问题的思路
(2)多线程的提出
①上次5.9收到数据包,调用ngx_wait_handler_proc_p1收到数据包,然后调用ngx_wait_request_handler_proc_plast把数据包扔到消息队列inMsgRecvQueue中来,接下来解析数据包,处理结果《《–用线程来处理问题
②一个进程 跑起来之后缺省 就自动启动了一个 “主线程”,也就是我们一个worker进程一启动就等于只有一个“主线程”在跑;我们现在涉及到了业务逻辑层面,这个就要用多线程处理,所谓业务逻辑:充值,抽卡,战斗;
1)例如:充值,需要本服务器和专门的充值服务器通讯,一般需要数秒到数十秒的通讯时间。此时,我们必须采用多线程【100个多线程】处理方式;
2)一个线程因为充值被卡住,还有其他线程可以提供给其他玩家及时的服务(这里线程于iocp没关系,只处理逻辑);
(iocp(windows)启动线程数为cpu*2+2;)
3)互斥:
a)主线程 往消息队列中用inMsgRecvQueue()扔完整包(用户需求),那么一堆线程要从这个消息对列中取走这个包,所在必须要用互斥;
b)引入变量m_recvMessageQ,定义消息队列互斥量
在这里插入图片描述
1))在ngx_c_socket.cxx构造类中初始化互斥量在这里插入图片描述
2))在ngx_c_socket.cxx析构函数中销毁从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第1张图片
3))在ngx_c_socket_requests.cxx中的inMsgRecvQueue()启动CLock(实现自动加锁解锁,在ngx_c_lockmutex.h中)
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第2张图片
自动加锁解锁,irmqc把消息队列的数字返回去从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第3张图片
4))outMsgRecvQueue()从消息队列中取数据,这个函数返回的是字符串
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第4张图片
(一个主线程放消息,多个子线程从消息队列中取消息)

4)多线程名词
a)POSIX:表示可移植操作系统接口(Portable Operating System Interface of UNIX)。
b)POSIX线程:是POSIX的线程标准【大概在1995年左右标准化的】;它定义了创建和操纵线程的一套API(Application Programming Interface:应用程序编程接口),说白了 定义了一堆我们可以调用的函数,一般是以pthread_开头,比较成熟,比较好用;我们就用这个线程标准;
c)现在是NPTL线程

(3)线程池实战代码
(3.1)为什么引入线程池
1)线程池:说白了 就是 我们提前创建好一堆线程,并搞一个雷来统一管理和调度这一堆线程【这一堆线程我们就叫做线程池】,
①当来了一个任务【来了一个消息】的时候,我从这一堆线程中找一个空闲的线程去做这个任务【去干活/去处理这个消息】,
②活干完之后,我这个线程里边有一个循环语句,我可以循环回来等待新任务,再有新任务的时候再去执行新的任务;
③就好像这个线程可以回收再利用 一样;
2)线程池存在意义和价值;
①实现创建好一堆线程,避免动态创建线程来执行任务,提高了程序的稳定性;有效的规避程序运行之中创建线程有可能失败的风险;
②提高程序运行效率:线程池中的线程,反复循环再利用;
但是说到根上,用线程池的目的无非就两条:提高稳定性,提升整个程序运行效率,容易管理【使编码更清晰简单】

(4)线程池的使用
1)引入misc中的新文件ngx_c_threadpool.cxx建立线程池和头文件ngx_c_threadpool.h
还要在common.mk中72行加上-lpthread
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第5张图片
2)ngx_c_threadpool.h有一个类叫CTreadPool
Create创建线程池
StopAll()使线程池所有线程退出
Call()来任务了,调用线程池的一个线程出来工作
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第6张图片
3)在类中定义了类的结构
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第7张图片
4)配置文件nginx.conf中配置线程池数量
在这里插入图片描述
5)bool CTreadPool线程池管理类:用来管理线程池
6)线程池的线程
为了避免线程池的异常,所有线程必须都卡在pthread_cond_wait(&m_pthreadCond,&mpthreadMutex);才认为线程启动起来,这个函数会释放互斥量,都会卡在这
7)静态成员函数,是不存在this指针的
从零构建通讯器--6.1业务逻辑之多线程、线程池实战(接受数据放到消息队列中,主要讲了线程池的create)_第8张图片
8)线程池精华代码
在这里插入图片描述
从消息队列中拿出一个请求,且系统不是关闭状态的
(4.1)线程池的初始化
(4.2)线程池工作的激发
(4.3)线程池完善和测试

你可能感兴趣的:(通讯器项目实现,c++,多线程)