我正在尝试编写一个异步日志记录类,但无法决定何时将日志写入该文件。
现在,我正在考虑将所有日志存储在一个向量中,然后根据它们的时间戳对它们进行排序。
问题是我应该在什么时候将日志写到文件中?如果我在写入磁盘之前等待N个日志,我可能会遗漏一个日志条目,或者如果我们已经达到向量中的N个日志条目,那么一个日志条目可能会被无序地写入日志。
我在想也许可以使用某种计时器,但我不确定这样做会不会更好。
如果您有任何想法,我将不胜感激,谢谢。
发布于 2012-09-12 10:00:50
我同意关于在没有缓冲(或显式刷新)的情况下无序编写它们的评论。但是,如果您想按顺序编写它们,我会有一个单独的线程来管理编写。您可以定义一个特定的滞后量(大概以秒为单位),这样您就可以合理地保证覆盖所有迟到的人。
所以在非常基本的意义上,你会有一个线程函数,类似于:
time_t writeDelay = 10; // 10 seconds
for(;;)
{
// Sleep for a second
//[OS-specific code here]
time_t now;
time(&now);
WriteLogEntriesUpTo(now - writeDelay);
}这里的问题是,如果您没有正确地将日志条目排序到一个向量中,可能会给您的记录器带来大量开销。至少要使用deque,这样就可以很容易地从前面弹出条目。如果我要这样做,我可能会在我的队列中为我的日志字符串和简单记录设置一个大缓冲区(实际上是一个内存池)。带有时间戳和指针的东西会使排序变得很容易。
struct LogEntry {
time_t timestamp;
char *message;
};我没有把它们放在deque中,而是实现了某种有序列表(同样,内存池)。要让这一切变得快速,那将是相当繁琐的。你想得越多,就越有必要乱写。
发布于 2012-09-13 00:59:29
如果您正在处理异步日志记录,我建议您使用线程安全队列将所有带有时间戳的消息发送到日志记录线程工作线程。然后,日志工作人员可以在一个块中处理出现在队列中的所有消息。
这种线程安全的队列抽象允许您设置缓冲区大小或使其不受限制(如果队列/缓冲区通过条件变量填满,则可以向线程发送消息),同时记录多个线程的日志,如果您将主线程包装在try catch循环中,该循环将等待记录器完成,然后退出(好吧,它不会对段错误有帮助,但它仍然有助于大多数错误),即使在错误发生后也可以记录进程日志。此外,您可以将消息传递到记录器,然后在主程序线程中继续执行,而无需等待任何IO操作(这可能会大大缩短执行时间)。它也不难实现。队列的API非常有限,因此您与数据结构的交互只能包装一个带有范围锁定的列表。
您为此实现付出了很小的代价--即锁定价格。但是,如果您需要添加任何其他多线程,则不必重新构建记录器,并且通过将IO卸载到另一个线程,您可能会比单线程记录器运行得更快。
如果您有乱序的消息,您有两个选择。在队列的日志工作进程端进行日志排序(为工作进程保留一个本地缓冲区,以保存较旧的消息)。或者将日志队列的实现更改为优先级队列,使用时间戳对消息进行排序,并在插入时支付更高的代价。后者可能更容易实现,但需要付出更高的同步代价。
我在使用Boost线程的C++中使用了这个策略,它工作得很好。我可以崩溃,但仍然可以从崩溃之前获得日志,当我将工作分支到各种线程中以便于并行化工作时,我只是在任何地方都使用相同的日志抽象,以便于跟踪事件排序。
https://stackoverflow.com/questions/12379505
复制相似问题