Поиск процессов с использованием ALSA звучит быстро - PullRequest
5 голосов
/ 08 февраля 2009

В настоящее время способ, которым /usr/sbin/alsa в Debian знает процессы, использующие звуковую карту, выглядит так:

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.

Обновление: я открыл ошибку Debian по теме.

Ответы [ 3 ]

14 голосов
/ 08 февраля 2009

Ответ на этот вопрос есть в ALSA FAQ . В моей системе использование fuser намного быстрее, чем использование lsof.

fuser -v /dev/snd/*
3 голосов
/ 20 июня 2009

Вы начинаете много процессов здесь. Вместо этого вы можете попробовать сделать аналогично тому, как вы написали скрипт lsof ... но заменив lsof оболочкой для цикла:

Если вы хотите избежать запуска большого количества процессов 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 почти всегда встроен в оболочку), но я думаю, это больше из-за плохих методов тестирования. Попробуйте сами.

1 голос
/ 09 февраля 2009

Вы не говорите, какие временные рамки вы ищете, но для альтернативного предложения

for i in /proc/[0-9]*/fd/*;

может работать и немного ускорить работу, как если бы вы использовали cut вместо awk.

...