我可以"force"线程唤醒吗?

Can I "force" thread to wake up?

本文关键字:唤醒 线程 force 我可以      更新时间:2023-10-16

我想实现一个快速记录器,它保存日志条目,当某个触发器到达时,它会刷新最后X条消息。

因此,我们的想法是将所有消息保存在一个循环缓冲区中,一旦我们有了触发器,就将其ID推送到另一个线程(整个系统中的一个线程)监视的队列中。这个线程将返回X条消息并刷新它们。我知道如何处理在我尝试刷新时编写的消息,在我刷新之前被覆盖的消息,以及在我尝试更新它们时被刷新的消息等等。

我的问题是,例如,如果我有20个线程在写消息,而只有10个内核,那么在2个"编写器"线程执行之间的时间差中,所有缓冲区都将被覆盖几次。

"我的"线程有没有办法"强制"编写器"线程执行(或者给它一个时间片?我想没有,但仍然。。。你能就克服这个问题的其他方法/设计提出建议吗。

据我所知,一旦队列中有新的ID可用,您就希望立即恢复线程。锁定基元是可能的——编写器线程应该休眠,直到收到触发线程的通知。如何实现这种行为取决于您正在使用的多线程框架。

例如,在C++11中,您可以查看std::condition_variable

编辑正如评论中所提到的,磁盘IO很慢,因此您需要将消息提取到编写器线程中的内存中,然后再将它们写入磁盘。在IO期间,缓冲区可以被到达的消息覆盖。

我以前写过类似的东西,其中对日志方法的调用实际上被放置在另一个线程(T-Logger)监视的队列中。这使其他线程不必调用底层日志API,并且在低延迟应用程序中运行良好。

如果您想显式缓冲,然后在触发器上写入,那么我仍然建议从一个线程(如T-Logger)执行所有写入操作,然后使用某种条件变量向T-Logger发出信号,表明它现在应该将队列中的项目写入底层日志文件。

正如问题评论中提到的,你应该避免让多个线程尝试IO。IO速度非常慢,让所有线程都尝试写入一个文件会导致他们放弃等待IO完成的CPU周期。

听起来像是使用信号量的经典案例,用循环缓冲区的长度初始化。来自需要记录内容的线程的日志调用必须在继续之前从信号量中获得一个单元,并且日志线程在从队列中提取条目时向信号量发出信号。如果缓冲区用完,那么任何试图进行日志记录的线程都将被阻塞,直到有空间容纳其日志条目为止。

显然,日志项的循环缓冲区/队列/任何容器都必须是线程安全的。