curve源码分析 chunkserver_concurrent_apply(concurrent_apply.cpp)

源码路径
curve-release2.2\src\chunkserver\concurrent_apply

以下是对concurrent_apply.cpp文件中源码的详细分析,我将在代码中添加注释以解释每一部分的功能和作用。

/*
 *  Copyright (c) 2020 NetEase Inc.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

// 引入必要的头文件
#include <glog/logging.h>  // 用于日志记录
#include <algorithm>  // 用于算法支持
#include <vector>  // 用于动态数组
#include "src/chunkserver/concurrent_apply/concurrent_apply.h"  // 引入并发应用模块的头文件
#include "src/common/concurrent/count_down_event.h"  // 用于倒计时事件

using ::curve::common::CountDownEvent;  // 使用CountDownEvent

namespace curve {
namespace chunkserver {
namespace concurrent {

// ConcurrentApplyModule类的初始化方法
bool ConcurrentApplyModule::Init(const ConcurrentApplyOption &opt) {
    // 如果并发模块已经启动,则记录警告并返回
    if (start_) {
        LOG(WARNING) << "concurrent module already start!";
        return true;
    }

    // 检查并发选项参数是否有效,并进行初始化
    if (false == checkOptAndInit(opt)) {
        return false;
    }

    // 设置启动标志为true
    start_ = true;
    // 初始化条件变量,用于等待线程池初始化完成
    cond_.Reset(opt.rconcurrentsize + opt.wconcurrentsize);
    // 初始化读取并发线程池
    InitThreadPool(ThreadPoolType::READ, rconcurrentsize_, rqueuedepth_);
    // 初始化写入并发线程池
    InitThreadPool(ThreadPoolType::WRITE, wconcurrentsize_, wqueuedepth_);

    // 等待线程池初始化完成,超时时间为5000毫秒
    if (!cond_.WaitFor(5000)) {
        LOG(ERROR) << "init concurrent module's threads fail";
        start_ = false;  // 重置启动标志
    }

    // 记录线程池初始化成功的日志
    LOG(INFO) << "Init concurrent module's threads success";
    return start_;  // 返回启动状态
}

// 检查并发选项参数并进行初始化的方法
bool ConcurrentApplyModule::checkOptAndInit(const ConcurrentApplyOption &opt) {
    // 检查参数是否满足条件,即是否大于0
    if (opt.rconcurrentsize <= 0 || opt.wconcurrentsize <= 0 ||
        opt.rqueuedepth <= 0 || opt.wqueuedepth <= 0) {
        // 如果参数不满足条件,记录日志并返回失败
        LOG(INFO) << "init concurrent module fail, params must >=0"
                   << ", rconcurrentsize=" << opt.rconcurrentsize
                   << ", wconcurrentsize=" << opt.wconcurrentsize
                   << ", rqueuedepth=" << opt.rqueuedepth
                   << ", wqueuedepth=" << opt.wqueuedepth;
        return false;
    }

    // 更新成员变量以保存读取和写入的并发大小及队列深度
    wconcurrentsize_ = opt.wconcurrentsize;
    wqueuedepth_ = opt.wqueuedepth;
    rconcurrentsize_ = opt.rconcurrentsize;
    rqueuedepth_ = opt.rqueuedepth;

    return true;  // 返回成功
}

// 初始化线程池的方法
void ConcurrentApplyModule::InitThreadPool(ThreadPoolType type, int concorrent, int depth) {
    // 为每个并发线程创建一个任务线程
    for (int i = 0; i < concorrent; i++) {
        auto asyncth = new (std::nothrow) taskthread(depth);  // 创建任务线程
        CHECK(asyncth != nullptr) << "allocate failed!";  // 检查分配是否成功

        // 根据线程池类型,将任务线程添加到对应的映射中
        switch (type) {
        case ThreadPoolType::READ:
            rapplyMap_.insert(std::make_pair(i, asyncth));  // 添加到读取线程池映射
            break;

        case ThreadPoolType::WRITE:
            wapplyMap_.insert(std::make_pair(i, asyncth));  // 添加到写入线程池映射
            break;
        }
    }

    // 为每个任务线程创建一个线程,并启动它们
    for (int i = 0; i < concorrent; i++) {
        switch (type) {
        case ThreadPoolType::READ:
            rapplyMap_[i]-eth = std::thread(&ConcurrentApplyModule::Run, this, type, i);  // 创建读取线程
            break;

        case ThreadPoolType::WRITE:
            wapplyMap_[i]-eth = std::thread(&ConcurrentApplyModule::Run, this, type, i);  // 创建写入线程
            break;
        }
    }
}

// 运行线程池中的任务的方法
void ConcurrentApplyModule::Run(ThreadPoolType type, int index) {
    // 通知条件变量,表示线程池中的线程已启动
    cond_.Signal();
    // 循环运行,直到停止标志被设置为false
    while (start_) {
        // 根据线程池类型,从对应的队列中弹出任务并执行
        switch (type) {
        case ThreadPoolType::READ:
            rapplyMap_[index]->tq.Pop();  // 执行读取任务
            break;

        case ThreadPoolType::WRITE:
            wapplyMap_[index]->tq.Pop();  // 执行写入任务
            break;
        }
    }
}

// 停止并发应用模块的方法
void ConcurrentApplyModule::Stop() {
    // 记录停止并发应用模块的日志
    LOG(INFO) << "stop ConcurrentApplyModule...";
    // 设置停止标志为false
    start_ = false;
    // 定义唤醒函数,用于唤醒等待的任务
    auto wakeup = []() {};
    // 遍历读取线程池映射,并停止所有读取线程
    for (auto iter : rapplyMap_) {
        iter.second->tq.Push(wakeup);  // 推送唤醒任务到队列
        iter.second->eth.join();  // 等待线程结束
        delete iter.second;  // 删除任务线程
    }
    rapplyMap_.clear();  // 清空读取线程池映射

    // 遍历写入线程池映射,并停止所有写入线程
    for (auto iter : wapplyMap_) {
        iter.second->tq.Push(wakeup);  // 推送唤醒任务到队列
        iter.second->eth.join();  // 等待线程结束
        delete iter.second;  // 删除任务线程
    }
    wapplyMap_.clear();  // 清空写入线程池映射

    // 记录停止并发应用模块成功的日志
    LOG(INFO) << "stop ConcurrentApplyModule ok.";
}

// 清空并发应用模块中所有任务的方法
void ConcurrentApplyModule::Flush() {
    // 创建倒计时事件,用于等待所有写入线程完成任务
    CountDownEvent event(wconcurrentsize_);
    // 定义刷新任务,用于清空队列
    auto flushtask = [&event]() {
        event.Signal();  // 触发事件以唤醒等待的线程
    };

    // 遍历写入线程池映射,并向每个队列推送刷新任务
    for (int i = 0; i < wconcurrentsize_; i++) {
        wapplyMap_[i]->tq.Push(flushtask);  // 推送刷新任务
    }

    // 等待所有写入线程完成任务
    event.Wait();
}

// 根据操作类型调度任务到相应的线程池的方法
ThreadPoolType ConcurrentApplyModule::Schedule(CHUNK_OP_TYPE optype) {
    // 根据操作类型返回相应的线程池类型
    switch (optype) {
    case CHUNK_OP_READ:
    case CHUNK_OP_RECOVER:
        return ThreadPoolType::READ;  // 读取操作使用读取线程池
    default:
        return ThreadPoolType::WRITE;  // 其他操作使用写入线程池
    }
}

}  // namespace concurrent
}  // namespace chunkserver
}  // namespace curve

这段代码定义了一个ConcurrentApplyModule类,它用于管理和执行并发任务。类中包含了初始化、停止、清空任务、调度任务以及运行任务的方法。

Init方法用于初始化并发模块,包括检查参数的有效性、初始化读取和写入线程池,并等待线程池初始化完成。

checkOptAndInit方法用于检查并发选项参数是否有效,并更新成员变量以保存读取和写入的并发大小及队列深度。

InitThreadPool方法用于初始化指定类型的线程池,为每个并发

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值