Linux多线程调度

4
我有一个程序在8核服务器上启动了约12个线程。其中一些线程正在等待关键数据。当使用循环中的recv时,recv将阻塞直到数据到达。然而,当有数据时,它需要尽快处理。
我注意到的一件事是,在连接处于静止状态时,线程没有太多活动。线程可能被置于睡眠状态(怀疑?),然后当数据进入时,需要先唤醒它,因此浪费时间。我想知道是否有任何方法可以设置,使线程不会被置于睡眠状态,并稍后唤醒?谢谢!

这就是抢占式系统的工作方式 - 线程调用recv()并阻塞。当有数据(或连接关闭或错误)时,recv()返回。时间不会浪费 - 当recv()线程“休眠”时,它本来要使用的CPU可用于其他事情,例如运行网络堆栈,以便尽快获取数据。 - Martin James
1
我明白了。由于我的线程数比核心数多,这会导致争用吗?还是我应该只在8核服务器上启动8个线程? - Daniel
如果你只是等待请求,并以CPU为主的方式处理它们,然后响应,那么可能没有比核心更多的线程意义。但是,如果你正在接收请求,等待非CPU资源(例如本地磁盘或向另一个服务器发送请求并等待响应),那么更多的线程应该会有所帮助。当然,在你的环境中,你总是可以进行测量并确定确切情况。 - Scott Lamb
2个回答

2

不仅仅是你的线程,还有其他线程。在一个大范围内,实际拥有多少线程并不重要。当你的线程正在等待 recv 时,调度程序可能会选择其他线程。因此,当有数据让你的 recv 返回时,你的线程将准备好运行,并且可能被调度程序选择执行。如果所有核心都被等于或高于你的线程优先级的线程占用,并且它们的时间片段不幸地没有结束,你的线程将不得不等待 CPU。 但是,为了在 recv 有数据后立即安排你的线程,你应该提高你的线程优先级。在这种情况下,recv 返回将使你的线程“可运行”,调度程序将在考虑任何低优先级的其他线程之前切换到它。如果必要,它甚至会停止比你的线程优先级低的线程。


2
正如马丁·詹姆斯所说,阻塞是一种正常的做法,无论是通过简单的recv还是通过事件驱动服务器中的epoll。如果你没有观察到真正可衡量的延迟问题,那么就不用担心。你正在做每个人都在做的事情。
而真正可衡量的延迟问题,我指的是你明确定义的目标(比如,在某种负载模式下,客户端测量的50%延迟为1毫秒,99.9%ile延迟为100毫秒,也许是突发性的,如果你关心阻塞的话)与现实之间的差异。
话虽如此,我听说过一些非常注重延迟的人抱怨内核在处理器没有足够工作使其保持繁忙时将其置于太深的睡眠状态,导致唤醒时延迟过高。我认为这是你需要在内核层面控制的事情,而不是在你的应用程序中。我一时也找不到延迟方面的具体数据,因此这是你需要测量的东西:找到(或创建)一种方法来控制它使用的最深睡眠状态并测量其影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接