多 CPU 服务器正在运行多个进程。一个进程有一个线程,该线程应始终处于旋转状态,使用分配给它的 100% CPU。我目前的方法(除了询问开发人员...)是使用strace
等待信息到达其打开的文件描述符的进程,并使用设置为recvfrom(2)
where 的进程连续检查它,并且当没有数据包从网络套接字读取时,方法返回 -1。erno
EAGAIN
我不习惯堆栈跟踪生产设置,而且这是确定此信息的一种笨拙方法。我四处寻找proc(5)
,认为 flags 字段的值可能有助于检查该进程是否正在使用以该模式/proc/[pid]/fdinfo
调用的套接字。open(2)
O_NONBLOCK
我目前正在努力对这个值进行逆向工程。我知道它代表文件状态和文件模式的按位或。所以我想我可以检查源头中open(2)
该特定内核上使用的常量的值,然后对它们进行按位或运算,直到找到与 中的值匹配的值fdinfo
。这似乎相当笨拙,如果有人可以验证上述方法(我目前还不能)或提供更优雅的解决方案,我将不胜感激。
我也知道fnctl(2)
可以将文件描述符设置为非阻塞状态,但目前我将其视为相当于打开
答案1
是的,这是检查套接字是否非阻塞的有效方法。
非阻塞套接字的值为 04000,非阻塞套接字/proc/<pid>/fdinfo
以八进制表示。
您可以使用 python 验证此行为。
Python 2.7.5 (default, Feb 19 2014, 13:47:28)
[GCC 4.8.2 20131212 (Red Hat 4.8.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import *
>>> import os
>>> from os import O_NONBLOCK
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.setblocking(0)
>>> print open("/proc/self/fdinfo/{0}".format(s.fileno())).read(4096)
pos: 0
flags: 04002
>>> if 04002 & O_NONBLOCK:
... print "yes"
... else:
... print "no"
...
yes
现在你知道了,我必须指出你的开发人员是做错了。如果他们想要使用非阻塞套接字,那很好 - 但是他们应该epoll(2)
在套接字上设置一个并在轮询上阻塞。
该计划获得没有什么来自read(2)
非阻塞套接字,产生EAGAIN
--事实上,结果是更差因为几乎所有的系统调用都是一个抢占点,内核无论如何都可以在此进行上下文切换。
这个开发人员浪费了本来可用于空闲线程的电力和 CPU 周期,而且实际上并没有从他/她认为这样做的好处中获益。
如果开发人员想要“缓存行”友好型,请将他的任务固定到特定的 CPU 上并完成它。