# 基于多设计模式的高性能日志系统 **Repository Path**: zhaobohan/zhaobohan-log ## Basic Information - **Project Name**: 基于多设计模式的高性能日志系统 - **Description**: 这是一个基于多设计模式的高性能日志系统的C++项目,在学习异步网络库时看到的项目,比较感兴趣,于是进行了学习和改造 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-09-02 - **Last Updated**: 2026-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 写在前面 最近在学习webserver中可能的优化场景,看到了一个有意思的优化点,就是对于日志系统的优化,突然回想起本人的webserver的项目主要是以同步直接进行打印到控制台的操作,想必性能是最差的一种情况,因此这里决定进行一个更变,对于日志模块进行优化,提供一个更加高性能的日志的组件 但是这个项目本身其实难度不大,只是可以作为一个组件来使用,这里就不详细讲述,只是进行一个简单的介绍 # 双缓冲区异步任务处理器(AsyncLooper)设计 设计思想:异步处理线程 + 数据池 使用者将需要完成的任务添加到任务池中,由异步线程来完成任务的实际执行操作。 任务池的设计思想:双缓冲区阻塞数据池 优势:避免了空间的频繁申请释放,且尽可能的减少了生产者与消费者之间锁冲突的概率,提高了任务处理效率。 在任务池的设计中,有很多备选方案,比如循环队列等等,但是不管是哪一种都会涉及到锁冲突的情况,因为在生产者与消费者模型中,任何两个角色之间都具有互斥关系,因此每一次的任务添加与取出都有可能涉及锁的冲突,而双缓冲区不同,双缓冲区是处理器将一个缓冲区中的任务全部处理完毕后,然后交换两个缓冲区,重新对新的缓冲区中的任务进行处理,虽然同时多线程写入也会冲突,但是冲突并不会像每次只处理一条的时候频繁(减少了生产者与消费者之间的锁冲突),且不涉及到空间的频繁申请释放所带来的消耗![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/11ac0a8d176f4211a5377717e7c3d18b.png) ```cpp /** * @file buffer.hpp * @brief 双缓冲区类设计 * @author zhaobohan (zhaobohan_free@163.com) */ #include #include #include #include #include #include #include #include #include namespace mylogs { #define BUFFER_DEFAULT_SIZE (1*1024*1024) #define BUFFER_INCREMENT_SIZE (1*1024*1024) #define BUFFER_THRESHOLD_SIZE (10*1024*1024) class Buffer { public: Buffer(): _reader_idx(0), _writer_idx(0), _v(BUFFER_DEFAULT_SIZE) {} bool empty() { return _reader_idx == _writer_idx; } size_t readAbleSize() { return _writer_idx - _reader_idx; } size_t writeAbleSize() { return _v.size() - _writer_idx; } void reset() { _reader_idx = _writer_idx = 0; } void swap(Buffer &buf) { _v.swap(buf._v); std::swap(_reader_idx, buf._reader_idx); std::swap(_writer_idx, buf._writer_idx); } void push(const char *data, size_t len) { assert(len <= writeAbleSize()); ensureEnoughSpace(len); std::copy(data, data+len, &_v[_writer_idx]); _writer_idx += len; } const char*begin() { return &_v[_reader_idx]; } void pop(size_t len) { _reader_idx += len; assert(_reader_idx <= _writer_idx); } protected: void ensureEnoughSpace(size_t len) { if (len <= writeAbleSize()) return; /*每次增大1M大小*/ size_t new_capacity; if (_v.size() < BUFFER_THRESHOLD_SIZE) new_capacity = _v.size() * 2 + len; else new_capacity = _v.size() + BUFFER_INCREMENT_SIZE + len; _v.resize(new_capacity); } private: size_t _reader_idx; size_t _writer_idx; std::vector _v; }; } ```