本文主要是介绍基于多反应堆的高并发服务器【C/C++/Reactor】(中)线程池的启动和从线程池中取出一个反应堆实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、线程池的启动
// 启动线程池
void threadPoolRun(struct ThreadPool* pool) {assert(pool && !pool->isStart);if(pool->mainLoop->threadID != pthread_self()) {exit(0);}pool->isStart = true;if(pool->threadNum) {for(int i=0;i<pool->threadNum;++i) {workerThreadInit(&pool->workerThreads[i], i);workerThreadRun(&pool->workerThreads[i]);}}
}
## 学习笔记:线程池的运行机制
- 线程池被创建后,需要启动使其子线程运行。启动线程池的函数需要一个有效struct ThreadPool*类型指针pool作为参数,和threadNum代表子线程总个数
// 初始化线程池
struct ThreadPool* threadPoolInit(struct EventLoop* mainLoop, int threadNum);
- 确保线程池未运行且执行线程为主线程
// 确保线程池未运行
assert(pool && !pool->isStart);
// 比较主线程的ID和当前线程ID是否相等
// 相等=>确保执行线程为主线程;不相等=>exit(0)
if(pool->mainLoop->threadID != pthread_self()) {exit(0);
}
- 如果条件满足,将线程池标记为已启动,并初始化并启动子线程
- 如果线程数量大于零,通过WorkerThread模块的workerThreadInit函数进行初始化,通过WorkerThread模块的workerThreadRun函数进行启动
pool->isStart = true; // 标记为启动
if(pool->threadNum) { // 线程数量大于零for(int i=0;i<pool->threadNum;++i) {workerThreadInit(&pool->workerThreads[i], i);// 初始化子线程workerThreadRun(&pool->workerThreads[i]); // 启动子线程}
}
### 知识点:线程池的启动
- 启动线程池的函数需要确保传入的结构体指针有效且线程池未运行
- 执行线程需要判断是否为主线程,避免异常情况
- 成功启动后,需要初始化并启动子线程,通过WorkerThread模块的函数进行初始化和启动
二、从线程池中取出一个反应堆实例
此外,takeWorkerEventLoop函数可以从线程池中取出某个子线程的反应堆实例
// 取出线程池中的某个子线程的反应堆实例
struct EventLoop* takeWorkerEventLoop(struct ThreadPool* pool) {assert(pool->isStart);if(pool->mainLoop->threadID != pthread_self()) {exit(0);}// 从线程池中找到一个子线程,然后取出里边的反应堆实例struct EventLoop* evLoop = pool->mainLoop; if(pool->threadNum > 0) {evLoop = pool->workerThreads[pool->index].evLoop;pool->index = ++pool->index % pool->threadNum;}return evLoop;
}
如果线程数量为零,线程池可以提供一个事件循环的反应堆模型(mainLoop),即:
evLoop=pool->mainLoop;
如果线程数量大于零,从线程池中的当前工作线程获取其事件循环,并将其存储在evLoop
变量中。为了对线程池中的工作线程实现雨露均沾,故需要用到index这个变量,为了确保 pool->index 的值在合适的取值范围内,并且不会超出它的取值范围:先将 pool->index 的值加一,然后对 pool->threadNum取余数,并将结果赋值给 pool->index
if(pool->threadNum > 0) {evLoop = pool->workerThreads[pool->index].evLoop;pool->index = ++pool->index % pool->threadNum;
}
### 知识点:子线程的反应堆实例的取出
- 可以通过takeWorkerEventLoop函数从线程池中取出子线程的反应堆实例
- 这个函数的核心是取出反应堆实例,用于处理任务
- 如果线程数量为零,线程池可以提供一个事件循环的反应堆模型(mainLoop)
- 对线程池中的工作线程实现雨露均沾,用到index这个变量
未完待续~
这篇关于基于多反应堆的高并发服务器【C/C++/Reactor】(中)线程池的启动和从线程池中取出一个反应堆实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!