我想实现一个保存日志条目的快速记录器,当某个触发器到达时,它会刷新最后的X个消息。
所以我的想法是将所有消息保存在循环缓冲区中,一旦我们有了触发器,就将它的ID推送到另一个线程监视的队列(整个系统中的一个线程)。该线程将返回X消息并刷新它们。我知道如何处理在我尝试刷新时正在写入的消息,在我刷新在我尝试更新它们时刷新的消息之前已被覆盖的消息等。
我的问题是,如果我有20个线程编写消息,而且只有10个核心,在2个“编写器”线程执行之间的时间差,所有缓冲区将被覆盖几次。
“我的”线程是否可以“强制”执行“编写”线程(或者给它的时间片?我猜不会但仍然...... 你能否以任何其他方式/设计提出建议来克服这个问题。
答案 0 :(得分:1)
据我了解,只要队列中有新ID,您就想恢复线程。有可能使用锁定原语 - 您的写入程序线程应该在您的触发器线程通知之前一直处于休眠状态。如何实现此行为取决于您正在使用的多线程框架。
例如,在C ++ 11中,您可以查看std::condition_variable
。
编辑。正如评论中所提到的,磁盘IO很慢,因此您需要在写入程序线程中将消息提取到内存,然后才将它们写入磁盘。在IO期间,缓冲区可以被到达的消息覆盖。
答案 1 :(得分:0)
之前我写了类似的东西,其中对日志方法的调用实际上放在另一个线程(T-Logger
)监视的队列上。这使得其他线程不必调用底层日志API,并且在低延迟应用程序中运行良好。
如果你想显式缓冲然后写入一个触发器,那么我仍然建议你从一个线程(例如T-Logger
)执行所有写操作,然后使用某种conditional variable来发信号给T-Logger
它现在应该将队列中的项目写入基础日志文件。
如问题评论中所述,您应避免让多个线程尝试执行IO。 IO速度令人难以置信,让所有线程尝试写入文件会导致它们放弃CPU周期等待IO完成。
答案 2 :(得分:0)
听起来像使用信号量的经典案例,用循环缓冲区的长度初始化。来自需要记录东西的线程的日志调用必须在继续之前从信号量获取一个单元,并且日志记录线程在从队列中提取条目时发信号通知信号量。如果缓冲区用完,任何尝试记录的线程都将阻塞,直到其日志条目有空间。
显然,循环缓冲区/队列/日志条目的任何容器必须是线程安全的。