基于BOOST 多线程的日志类

来源:互联网 发布:各种网络协议 编辑:程序博客网 时间:2024/06/05 18:03

一篇基于BOOST库多线程的日志,才疏学浅,仅此抛砖引玉而已。
日志操作大致分为两种(本人拙见):
A 插入日志,实时写入到文件(好处:实时保存了程序的运行信息,不便之处对于高并发的网络操作则严重影响IO性能)

B 前端只管往日志容器(暂定为list)添加日志信息,后端开启工作线程,不断从容器内取出信息,写入到文件。(好处:读写分离能较高适应高并发环境的io操作,不便之处:程序意外宕机,还缓存在容器中的日志无法写入到文件内)
具体情况,具体分析,对于工业自动化控制设备,以及流程比较重要的软件来说,方法A是比较好的,当然,对于大型服务器框架来说,B是更好的选择。

下面代码仅仅是简单演示下B方法的流程设计,才能有限,未能考虑其他方面的知识。

class Logger;提供日志标准输出以及文件输出(转载于网络大神)
class CLog ;提供日志容器主线程写入操作,工作线程读取容器操作。

void    handle_work( );     //工作函数,从list列表中取出数据输出typedef list<std::string> LISTLOG; LISTLOG m_list_log;         //日志容器bool    m_bExit;boost::mutex            _mutex;//用于日志容器锁boost::mutex            _io_mutex;//标准输出流/文件锁boost::thread_group     _group_threads; //boost线程组int n_un_read;  //未能读取日志数量int n_capacity; //定义日志存储容量boost::condition_variable_any cond_not_empty, cond_not_full;  //list容器未空,未满条件变量bool is_full(){return n_un_read == n_capacity;}bool is_empty(){return n_un_read == 0;}

主线程插入操作

bool CLog::insertLog(boost::string_ref strLog)

{

std::string strInfo = boost::posix_time::to_iso_string(microsec_clock::universal_time() + hours(8));  int pos = strInfo.find('T');    strInfo.replace(pos,1,std::string("-"));    strInfo.replace(pos + 3,0,std::string(":"));    strInfo.replace(pos + 6,0,std::string(":"));  strInfo += ":"; //格式化时间strInfo = strInfo + strLog.to_string(); //格式化时间+内容{      boost::mutex::scoped_lock lock(_mutex);  //局部域锁    while(is_full())  //判断日志容器是否已满    {          cond_not_full.wait(_mutex);  //等待容器未满信号    }      m_list_log.push_back(strInfo); //写入log容器    ++n_un_read;  }  cond_not_empty.notify_one();  //通知容器已不为空信号return true;

}

读取日志容器操作
void CLog::handle_work()
{

while(! m_bExit){    std::string strLog;    {          boost::mutex::scoped_lock lock(_mutex);  //局部域锁        while(is_empty())          {              cond_not_empty.wait(_mutex);          }          boost::this_thread::sleep(boost::posix_time::microsec(1)); //延时1ms,此处也可作为外部操作该线程中断(Interrupt)        --n_un_read;          if(!is_full())            cond_not_full.notify_one();         strLog = m_list_log.front();         m_list_log.pop_front();    }    //cout<<strLog<<endl;     if(strLog.size() != 0)    {            boost::mutex::scoped_lock lock(_io_mutex);  //输出流也需要锁来保护            LOG(INFO)<<strLog<<endl;     }}

}

初始化线程组
void CLog::init(int nThreads)
{

for (int i = 0; i < nThreads; i++){    boost::function0< void> fun =  boost::bind(&CLog::handle_work,this);    _group_threads.create_thread(fun); }

}

测试:简单写入10000条信息。

CLog log(10);//日志容器为10for (int i =0;  i < 10000; i++){    string s = boost::lexical_cast<string>(i);    log.insertLog(s);    boost::this_thread::sleep(boost::posix_time::microsec(1));  }

结构大体如上,只是简单演示下流程。
考虑不周的请大神多多指点。

原创粉丝点击