需求:实现一个类,要求这个类能实现日志的异步打印,打印信息包含时间,文件名,行号,进程号以及用户的打印信息。
这个需求里面的技术点。
1.异步的实现,肯定需要利用到线程?怎么保证线程同步?
2.文件名行号的获取?
3.怎么实现类似于printf的格式化输出的效果?
第一个问题:实现异步写日志
利用stl标准库里面的std::thread,结合std::mutex(共享锁)和std::condition_variable(条件变量)来实现。
另外这个类里面需要定义一个list类,list于vector类似,但是实现是基于双向链表的。在工作线程中,我们只需要将需要打印的string类加入到类Log的list链表内,同时notify_one()唤醒一次工作线程即可(该函数与notify_all()功能类似,都是用来唤醒线程),这里唤醒一次,处理一次队列里面的内容,然后线程休眠,阻塞在wait处。
多线程相关建议使用C++11的stl标准库。
对应的类是std::thread类,构造方法是std::thread(function,arg…);
相关的辅助类方法有
std::thread.join() //等待thread执行,再返回调用线程执行
std::thread.detatch() //线程分离
std::thread.joinable() //判断线程是否可以join
std::thread.get_id() //获取线程id
yield(); //当前线程放弃执行
在多线程调用时,需要用到锁。比如对类中的待打印队列进行操作时,如果不加锁,就很可能出现多个线程同时对类的打印队列进行操作。
最初始的mutex锁使用方法比较简单,如下
mutex m;
void func()
{
m.lock();
//do something
m.unlock();
}
以前的这种形式在很多时候容易出现忘记解锁的情况,导致出现死锁。
所以新的版本又出现了lock_guard,这个可以不用用户手动解锁,构造一个类,在出作用域的时候会直接调用析构函数帮用户解锁,避免出现死锁的情况。
mutex m;
void func()
{
std::lock_guard<mutex > mylock(m); //这里在构造的时候就已经上锁了
//dosomething
//函数结束时自动调用mylock的析构函数释放锁
}
lock_guard也可以通过传入两个参数来手动上锁,另外声明的lock_guard是不能手动加锁解锁的。
后面又引入了一个新的类unique_lock,他是lock_guard的升级版,用法更加丰富,可以通过构造参

最低0.47元/天 解锁文章
9489

被折叠的 条评论
为什么被折叠?



