العثور على العمليات باستخدام صوت ALSA بسرعة
سؤال
حاليا الطريق /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
.أنا أبحث عن حل POSIX بدون lsof
, ربما باستخدام /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 هو الجاني.
تحديث:لقد فتحت أ علة ديبيان حول هذا الموضوع.
المحلول
تبدأ الكثير من العمليات هنا.بدلاً من ذلك، يمكنك محاولة القيام بطريقة مشابهة للنص البرمجي lsof الذي نشرته...ولكن استبدال lsof بـ Shell for حلقة:
إذا كنت تريد تجنب إطلاق الكثير من عمليات grep، فابدأ بعملية واحدة فقط:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
echo ${i%/fd/*} $(readlink $i)
done | grep -q /dev/snd/pcm
يستغرق هذا الآن 4.5 ثانية على سطح المكتب، مقارنة بـ 7.5 ثانية عندما تكون هناك عملية grep واحدة لكل ملف مفتوح.
لكن...أعتقد أن grep الخاص بك ليس ضروريًا هنا.إذا كنت تهتم كثيرًا، يمكنك تجربة ما يلي:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
var="$(readlink $i)"
if test x"$var" != x"${var#/dev/snd/pcm}"
then
echo $i
fi
done
وهذا أسرع بالنسبة لي (test
غالبًا ما تكون الصدفة مدمجة)، ولكن أعتقد أن السبب في ذلك يرجع إلى طرق الاختبار السيئة.جرب بنفسك.
نصائح أخرى
هناك إجابة لهذا السؤال على الأسئلة الشائعة حول ALSA.على نظامي، يعد استخدام وحدة الصهر أسرع بكثير من استخدام lsof.
fuser -v /dev/snd/*
أنت لا تذكر نوع الجداول الزمنية التي تبحث عنها، بل تذكر اقتراحك البديل
for i in /proc/[0-9]*/fd/*;
قد يعمل ويمنحك القليل من السرعة، كما قد يحدث عند الاستخدام cut
بدلا من awk
.