我试图弄清楚为什么 Eclipse 会旋转,所以我决定启动 strace。
我使用以下命令找到了 eclipse 进程:
$ ps ax | grep java
5546 ? Sl 19:04 /usr/bin/java ... [arguments omitted]
通过运行strace
此进程,我发现它正在等待另一个进程:
$ sudo strace -p 5546
Process 5546 attached - interrupt to quit
futex(0x7f6c416679d0, FUTEX_WAIT, 5547, NULL^C <unfinished ...>
Process 5546 detached
有趣的是,进程 5547 没有出现ps
(谁能告诉我为什么?),但我可以strace
。它反复吐出大量 EAGAIN 失败(偶尔成功)
read(16, 0x7f6c41664d10, 16) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(15, 0x7f6c3815f2e4, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
clock_gettime(CLOCK_MONOTONIC, {67410, 357843264}) = 0
poll([{fd=16, events=POLLIN}, {fd=15, events=POLLIN}, {fd=68, events=POLLIN}, {fd=128, events=POLLIN}, {fd=69, events=POLLIN}], 5, 0) = 0 (Timeout)
read(16, 0x7f6c41664cb0, 16) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(15, 0x7f6c3815f2e4, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
...
从输出来看,它似乎正在轮询文件描述符 16、15、68、128 和 69。具体来说,从和调用EAGAIN
可以看出,错误来自 fds 15 和 6 。read(2)
recvfrom(2)
我如何找到有关这些 fds 的更多信息?我试过了,lsof -p 5547
但没有打印任何输出。我怀疑这些是向某个网站开放的套接字,但为什么它会陷入一个不断EAGAIN
失败的紧密循环中,这令人费解……
答案1
有些 PID 没有列出,因为它们属于线程.htop
可以按 来显示它们Shift+H(也可以选择T显示树形视图),但lsof
需要主进程的 PID。(无论如何,进程中的所有 pthread 都共享文件描述符。)您还可以查看/proc/5546/fd/
和/proc/5546/task/
。
EAGAIN 对于非阻塞 I/O 而言是正常的;例如,read()
当没有数据可读取时,就会返回该错误。请参阅阅读(2),写入(2)等等。其中一些 fd 可能是与 X11 服务器的连接 – X11 客户端库使用非阻塞 I/O。
答案2
第三个参数futex(2)
不一定是进程 ID,手册上说是futex(uaddr, op, val, timeout, ...)
,如果 op 是FUTEX_WAIT
,它“原子地验证 futex 地址u地址仍然包含值瓦尔,并在此 futex 地址上休眠,等待 FUTEX_WAKE。[何时]暂停为NULL,则调用无限期阻塞。”
在您的情况下,听起来好像进程 5546 正坐在那里等待某些东西 - 大概是它的线程 5547 或某些相关的东西,但我们无法仅基于此确切地知道是什么 - 将该数字写入指定的内存地址。
还要注意,您可以使用ps -eLf
或类似方法查看线程。