当前位置: 首页 > article >正文

从零开始实现一个C++高性能服务器框架----环境变量模块

此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善
项目地址:https://gitee.com/lzhiqiang1999/server-framework

简介

项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。
详细内容:日志模块,使用宏实现流式输出,支持同步日志与异步日志、自定义日志格式、日志级别、多日志分离等功能。线程模块,封装pthread相关方法,封装常用的锁包括(信号量,读写锁,自旋锁等)。IO协程调度模块,基于ucontext_t实现非对称协程模型,以线程池的方式实现多线程,多协程协同调度,同时依赖epoll实现了事件监听机制。定时器模块,使用最小堆管理定时器,配合IO协程调度模块可以完成基于协程的定时任务调度。hook模块,将同步的系统调用封装成异步操作(accept, recv, send等),配合IO协程调度能够极大的提升服务器性能。Http模块,封装了sokcet常用方法,支持http协议解析,客户端实现连接池发送请求,服务器端实现servlet模式处理客户端请求,支持单Reator多线程,多Reator多线程模式的服务器。

环境变量模块

  • 提供程序运行时的环境变量管理功能。这里的环境变量不仅包括系统环境变量,还包括程序自定义环境变量,命令行参数,帮助选项与描述,以及程序运行路径相关的信息。

1. 主要功能

  • 解析命令行参数,并提供参数的帮助描述
  • 获取系统环境变量
  • 获取当前程序运行的绝对路径,工作路径及配置文件的路径

2. 功能演示

int main(int argc, char** argv)
{
    johnsonli::EnvMgr::GetInstance()->addHelp("d", "run in daemon");
    johnsonli::EnvMgr::GetInstance()->addHelp("p", "print help");
    johnsonli::EnvMgr::GetInstance()->addHelp("s", "start in terminal");
    if(!johnsonli::EnvMgr::GetInstance()->init(argc, argv))
    {
        johnsonli::EnvMgr::GetInstance()->printHelp();
        return 0;
    }

    LOG_INFO(g_logger) << "exe: " << johnsonli::EnvMgr::GetInstance()->getExe();
    LOG_INFO(g_logger) << "cwd: " << johnsonli::EnvMgr::GetInstance()->getCwd();
    LOG_INFO(g_logger) << "path: " << johnsonli::EnvMgr::GetInstance()->getEnv("PATH", "XXX");


    if(johnsonli::EnvMgr::GetInstance()->has("p"))
    {
        johnsonli::EnvMgr::GetInstance()->printHelp();
    }

    return 0;

}

3. 模块介绍

3.1 Env

  • 处理当前命令行参数,系统环境变量,路径等问题。是一个单例模式
class Env
{
public:
    typedef RWMutex RWMutexType;
    bool init(int argc, char** argv);

    void add(const std::string& key, const std::string& val);
    bool has(const std::string& key);
    void del(const std::string& key);
    std::string get(const std::string& key, const std::string& default_value = "");

    void addHelp(const std::string& key, const std::string& desc);
    void removeHelp(const std::string& key);
    void printHelp();

    const std::string& getExe() const { return m_exe;}
    const std::string& getCwd() const { return m_cwd;}

    bool setEnv(const std::string& key, const std::string& val);
    std::string getEnv(const std::string& key, const std::string& default_value = "");

    std::string getAbsolutePath(const std::string& path) const;
    std::string getAbsoluteWorkPath(const std::string& path) const;
    std::string getConfigPath();

private:
    RWMutexType m_mutex;
    std::map<std::string, std::string> m_args;
    std::vector<std::pair<std::string, std::string> > m_helps;

    std::string m_program;  // 启动程序的名称
    std::string m_exe;      // 程序执行的绝对路径
    std::string m_cwd;      // 绝对路径的上一级路径
};

typedef johnsonli::Singleton<Env> EnvMgr;
  • 解析命令行参数。双指针的思路。调用readlink()系统调用,可以获取/proc/$pid/exe软链接文件指向的路径,该路径就是当前文件执行的绝对路径。
std::map<std::string, std::string> m_args; // 存环境变量参数
// 初始化,解析
bool init(int argc, char** argv);
// 添加到m_args
void add(const std::string& key, const std::string& val);
// 判断m_args有无该参数
bool has(const std::string& key);
// 删除
void del(const std::string& key);
// 获取
std::string get(const std::string& key, const std::string& default_value = "");
  • 获取/设置系统环境变量。主要使用getenv()setenv()两个系统调用
// 设置系统环境变量
bool Env::setEnv(const std::string& key, const std::string& val) 
{
    return !setenv(key.c_str(), val.c_str(), 1);
}

// 获取系统环境变量
std::string Env::getEnv(const std::string& key, const std::string& default_value) 
{
    const char* v = getenv(key.c_str());
    if(v == nullptr) 
    {
        return default_value;
    }
    return v;
}
  • 设置命令行参数帮助信息
std::vector<std::pair<std::string, std::string> > m_helps;	// 存帮助信息
void addHelp(const std::string& key, const std::string& desc);
void removeHelp(const std::string& key);
void printHelp();
  • getAbsolutePath方法,传入一个相对于执行文件的路径,返回这个路径的绝对路径。比如默认的配置文件路径就是通过getAbsolutePath(get(“c”, “conf”))来获取的,也就是配置文件夹默认在执行文件所在目录的conf文件夹。
std::string Env::getAbsolutePath(const std::string& path) const 
{
    if(path.empty())
    {
        return "/";
    }
    if(path[0] == '/')
    {
        return path;
    }
    return m_cwd + path;
}

std::string Env::getAbsoluteWorkPath(const std::string& path) const {
    if(path.empty()) {
        return "/";
    }
    if(path[0] == '/') {
        return path;
    }
    static johnsonli::ConfigVar<std::string>::ptr g_server_work_path =
        johnsonli::Config::Lookup<std::string>("server.work_path");
    return g_server_work_path->getValue() + "/" + path;
}

std::string Env::getConfigPath() 
{
    return getAbsolutePath(get("c", "conf"));
}

http://www.kler.cn/a/7432.html

相关文章:

  • 工化企业内部能源能耗过大 落实能源管理
  • sql注入之二次注入(sqlilabs-less24)
  • reduce-scatter:适合分布式计算;Reduce、LayerNorm和Broadcast算子的执行顺序对计算结果的影响,以及它们对资源消耗的影响
  • Fish Agent V0.13B:Fish Audio的语音处理新突破,AI语音助手的未来已来!
  • vue项目PC端和移动端实现在线预览pptx文件
  • Qt文件目录操作
  • 2 新建工程步骤
  • 045:cesium加载OpenStreetMap地图
  • 第十四届蓝桥杯模拟赛(第一期)——C语言版
  • 详解如何使用Nginx搭建文件服务器及实现文件服务
  • 询问ChatGPT的高质量答案艺术——提示工程指南(更新中……)
  • 什么是服务架构?微服务架构的优势又是什么?
  • 聚会Party
  • 剪枝与重参第四课:NVIDIA的2:4剪枝方案
  • 做了个springboot接口参数解密的工具,我给它命名为万能钥匙(已上传maven中央仓库,附详细使用说明)
  • 4.5--计算机网络之基础篇--1.模型分层--(复习+深入)---好好沉淀,加油呀
  • Elasticsearch:索引状态是红色还是黄色?为什么?
  • C++ 数组与字符串详解
  • 51单片机-LED篇
  • erpnext--指令
  • 多个硬盘挂载到同一个目录
  • 重新理解一个类中的forward()和__init__()函数
  • MyBatisPlus-DML编程控制
  • Muduo库源码剖析(八)——TcpServer类
  • 腾讯云轻量应用服务器价格表(2023版)
  • 前端学习:HTML基本标签