LINUX.ORG.RU

как переделать это в многопоточное ?

 , , , ,


1

0

Этот кусок кода выполняет то, что нужно. Конвертирует flac в mp3. Но делает это в один поток. Медленно. Коллекция конвертируется более суток. Как это переделать, чтобы можно было конвертировать не в один поток, а скажем в 4 ? Думаю, что это возможно сделать с помощью parallel. В баше врядли смогу осилить это, а в python не хочется лезть :(


find . -name "*.flac" | while read a; do
	OUTF=`echo "$a" | sed s/\.flac$/.mp3/g`
	ARTIST=`metaflac "$a" --show-tag=ARTIST | sed s/.*=//g`
	TITLE=`metaflac "$a" --show-tag=TITLE | sed s/.*=//g`
	ALBUM=`metaflac "$a" --show-tag=ALBUM | sed s/.*=//g`
	GENRE=`metaflac "$a" --show-tag=GENRE | sed s/.*=//g`
	TRACKNUMBER=`metaflac "$a" --show-tag=TRACKNUMBER | sed s/.*=//g`
	DATE=`metaflac "$a" --show-tag=DATE | sed s/.*=//g`

	flac -c -d "${a}" | lame -V 0 \
		-m j \
		--cbr \
		-b 192 \
		--noreplaygain \
		-q 0 \
		--lowpass 20.7 \
		--add-id3v2 \
		--pad-id3v2 \
		--ignore-tag-errors \
		--tt "$TITLE" \
		--tn "${TRACKNUMBER:-0}" \
		--ta "$ARTIST" \
		--tl "$ALBUM" \
		--ty "$DATE" \
		--tg "${GENRE:-12}" \
		- "$OUTF"

	rm -rf "${a}"
done


В баше же:

.... 
 echo "flac -c ... && rm -rf '$a'"
done | xargs -P 4 -n 1 -d $'\n' bash -c

Кавычками придётся пожонглировать.

DonkeyHot ★★★★★ ()
Последнее исправление: DonkeyHot (всего исправлений: 1)

Запустите 4 копии с разными масками, поменяв «*.flac» на одном «[A-O]*.flac», на другом «[P-Z]*.flac» и так же по русски. После чего запустите уже с изначальной маской для оставшихся.

vodz ★★★★★ ()
Ответ на: В баше же: от DonkeyHot

И всё же -P N -n 1 вызовет столько bash-ей при работе, сколько файлов. Проще сделать 4 списка файлов, а потом читать и выполнять не форкаясь по крайней мере для bash-а. Правда у ТСа ещё море пайпов и sed-ов в скрипте ...

vodz ★★★★★ ()

Изи же на bash-е.

#!/bin/bash
my_super_function()
{
    input="$1"
    OUTF=`echo "$a" | sed s/\.flac$/.mp3/g`
	ARTIST=`metaflac "$a" --show-tag=ARTIST | sed s/.*=//g`
	TITLE=`metaflac "$a" --show-tag=TITLE | sed s/.*=//g`
	ALBUM=`metaflac "$a" --show-tag=ALBUM | sed s/.*=//g`
	GENRE=`metaflac "$a" --show-tag=GENRE | sed s/.*=//g`
	TRACKNUMBER=`metaflac "$a" --show-tag=TRACKNUMBER | sed s/.*=//g`
	DATE=`metaflac "$a" --show-tag=DATE | sed s/.*=//g`

	flac -c -d "${a}" | lame -V 0 \
		-m j \
		--cbr \
		-b 192 \
		--noreplaygain \
		-q 0 \
		--lowpass 20.7 \
		--add-id3v2 \
		--pad-id3v2 \
		--ignore-tag-errors \
		--tt "$TITLE" \
		--tn "${TRACKNUMBER:-0}" \
		--ta "$ARTIST" \
		--tl "$ALBUM" \
		--ty "$DATE" \
		--tg "${GENRE:-12}" \
		- "$OUTF"

	rm -rf "${a}"
}
export -f my_super_function
find -type f -iname '*.flac' | parallel --no-notice my_super_function '{}'
Код не проверял, могут быть ошибки, как у тебя, так и у меня.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

и это запустит все 5к треков параллельно ?

Xwo ()
Ответ на: комментарий от Xwo

Не 5k треков, а столько, сколько ядер на машине, если конечно не настроено иначе в конфиге GNU parallel. А остальные треки в очереди постоят. При желании можно задать ключом к parallel нужное количество потоков, но я бы оставил дефолт.

peregrine ★★★★★ ()
Последнее исправление: peregrine (всего исправлений: 2)
Ответ на: комментарий от peregrine

Переписал my_super_function на нормальный bash. Не проверял.

my_super_function() {
        local l tag val
        local ARTIST TITLE ALBUM GENRE TRACKNUMBER DATE
        while read l; do
                tag=${l%%=*}
                val=${l#*=}
                case "${tag^^}" in
                 ARTIST) ARTIST=$val;;
                 TITLE) TITLE=$val;;
                 ALBUM) ALBUM=$val;;
                 GENRE) GENRE=$val;;
                 TRACKNUMBER) TRACKNUMBER=$val;;
                 DATE) DATE=$val;;
                esac
        done << EOF
$(metaflac --show-tag=ARTIST --show-tag=TITLE --show-tag=ALBUM --show-tag=GENRE --show-tag=TRACKNUMBER --show-tag=DATE "$1")
EOF
        flac -c -d "$1" | lame -V 0 -m j --cbr -b 192 --noreplaygain -q 0 \
                                 --lowpass 20.7 --add-id3v2 --pad-id3v2 \
                                 --ignore-tag-errors --tt "$TITLE" \
                                 --tn "${TRACKNUMBER:-0}" \
                                 --ta "$ARTIST" --tl "$ALBUM" \
                                 --ty "$DATE" --tg "${GENRE:-12}" \
                                 - "${1%flac}mp3"
        rm -f "$1"
}
vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от vodz

вызовет столько bash-ей при работе, сколько файлов

Правильно. На моём дохлом комутере это полторы секунды на килофайл. Время, потраченное ТС на поиски более оптимального решения, уже не окупается до 144 мегафайлов. Их столько есть в природе?

DonkeyHot ★★★★★ ()
Ответ на: комментарий от peregrine

Ну хорошо, переписал ваш код, чтобы не юзать GNU-parallel:

PARALLEL=4
jobs_is_parallel_available() {
        local -i i
        local l
        while true; do
                i=0
                while read l; do
                        i+=1
                done < <(jobs -r)
                [[ $i -lt $PARALLEL ]] && break
                sleep 0.1s
        done
}

while read l; do
   ### ASYNC
   my_super_function "$l" &
   jobs_is_parallel_available
done < <(find / -type f -iname '*.flac')
wait
Кстати, проверено - конвертирует.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от DonkeyHot

Время, потраченное ТС на поиски более оптимального решения, уже не окупается до 144 мегафайлов. Их столько есть в природе?

Видите ли, этот аргумент работает только при условии, что ТС и кушать не может, не решив эту задачу, больше не чем заняться не может. В обычной жизни — это уже жутко стандартный надоевший местный демагогический приём.

vodz ★★★★★ ()
Ответ на: комментарий от peregrine

Зачем?

А вдруг мне тоже надо сделать задачу ТСа, но parallel-я нет на компе? Тем более, что это так и есть на самом деле.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

демагогический приём

Это чисто арифметический приём. Грубо, «общая стоимость» = «стоимость поиска» + «количество»*«стоимость исполнения».

DonkeyHot ★★★★★ ()
Ответ на: комментарий от DonkeyHot

Это чисто арифметический приём.

Могу только повториться, этот приём работает только для роботов, ну и людских роботов, которые зарплату не могут получить и кушать им будет нечего, если они срочно не решат эту задачу.

А у нас имеется вот: Конвертирование flac/ape в mp3 с сохранением тегов , эта тема была 70 дней назад, с тем же самым скриптом.

vodz ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.