使用 ALSA 查找进程听起来很快
目前,Debian 中的 /usr/sbin/alsa
识别使用声卡的进程的方式如下所示:
echo $( \
lsof +D /dev -F rt \
| awk '/^p/ {pid=$1} /^t/ {type=$1} /^r0x(74|e)..$/ && type == "tCHR" {print pid}' \
| cut -c 2- \
| uniq \
)
这是相当难看的,并且依赖于 lsof
。 我正在寻找一个没有 lsof 的 POSIX 解决方案,也许使用 /proc。
time for i in /proc/*/fd/*; do readlink $i | grep -q /dev/snd/pcm && echo $i | awk -F '/' '{print $3}'; done | uniq
不幸的是,似乎需要比上面基于 lsof 的代码片段长两倍的时间。 你能否让它更快,以使其成为可行的替代品?
更新我将上面的内容重写为:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
if readlink $i | grep -q /dev/snd/pcm
then
IFS=/; set -- $i; unset IFS; echo $3
fi
done
但它似乎与我之前的代码片段具有相同的性能。 我怀疑 grep 是罪魁祸首。
更新:我已经针对该主题打开了 Debian bug。
Currently the way /usr/sbin/alsa
in Debian knows the processes using the sound card looks like:
echo $( \
lsof +D /dev -F rt \
| awk '/^p/ {pid=$1} /^t/ {type=$1} /^r0x(74|e)..$/ && type == "tCHR" {print pid}' \
| cut -c 2- \
| uniq \
)
Which is rather ugly and depends on lsof
. I am looking for a POSIX solution without lsof
, perhaps using /proc.
time for i in /proc/*/fd/*; do readlink $i | grep -q /dev/snd/pcm && echo $i | awk -F '/' '{print $3}'; done | uniq
Unfortunately seems to take twice as long as the lsof
based snippet above. Can you make it faster, in order to make it a viable replacement?
Update I rewrote the above as:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
if readlink $i | grep -q /dev/snd/pcm
then
IFS=/; set -- $i; unset IFS; echo $3
fi
done
But it seems to have the same performance as my earlier snippet. I suspect grep is the culprit.
Update: I have opened a Debian bug on the topic.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这个问题的答案 ALSA 常见问题解答。 在我的系统上,使用 fusionr 比使用 lsof 快得多。
There is an answer for this question on the ALSA FAQ. On my system, using fuser is way faster than using lsof.
您在这里启动了很多进程。 相反,您可以尝试以与您发布的 lsof 脚本类似的方式进行操作...但将 lsof 替换为 shell for 循环:
如果您想避免启动大量 grep 进程,请仅启动一个:
这在我的桌面上现在需要 4.5 秒,相比之下,每个打开的文件都有一个 grep 进程时需要 7.5 秒。
但是......我认为你的 grep 在这里是不必要的。 如果你很在意,你可以尝试:
这对我来说甚至更快(
test
几乎总是内置的shell),但我想这更多是因为糟糕的测试方法。 自己尝试一下。You start a lot of processes here. Instead you can try doing in a similar way to the lsof script you posted... but replacing lsof by a shell for loop:
If you want to avoid launching lots of grep processes, start only one:
This takes now 4.5s on my desktop, compared to 7.5s when there's one grep process for each opened file.
But... your grep is not necessary here, I think. If you care so much, you can try:
This is even faster for me (
test
is almost always a shell builtin), but I guess this is more because of bad testing methods. Try yourself.您没有说明您正在寻找什么样的时间尺度,但您的替代建议
可能会起作用并给您带来一点速度,就像使用
cut
而不是awk
。You don't say what kind of timescales you're looking for but for your alternative suggestion
might work and give you a bit of speed up, as might using
cut
rather thanawk
.