Привет, давай напишем очередной велосипед на Bash.
А напишем мы своё подобие команды cat, но с потоками.
Конечно можно воспользоваться дополнительной утилитой parallel, но мы лёгких путей не ищем. Глаза боятся, да руки веселятся.
Вот что у меня получилось:
#!/bin/bash
file=$1
threads=4
process_line() {
line="$1"
echo $line
}
export -f process_line
fifo="/tmp/fifo"
mkfifo "$fifo"
exec 3<>"$fifo"
rm "$fifo"
for ((i = 0; i < threads; i++)); do
echo >&3
done
while IFS= read -r line; do
read -u 3
{
process_line "$line"
echo >&3
} &
done < "$file"
wait
exec 3>&-
Не забываем chmod +x pcat.sh
Запускать так: ./pcat.sh input.txt
Теперь разбираемся:
threads указываем количество потоков для чтения текстового файла.
process_line = функция, которая будет обрабатывать строку, у меня это простое echo, но можно накручивать любую логику.
export -f = экспортируем функцию, чтобы функция была доступна в subprocess (этот момент ранее в постах мы с тобой уже разбирали, ссылку не дам, по поиску найдешь если интересно).
fifo = задействуем FIFO для контроля потоков (чуть ниже объясню что это такое за хуйня).
mkfifo = создаём именованный канал /tmp/fifo для контроля количества одновременно запущенных потоков.
for ((i = 0; i < threads; i++)); do = заполняем каналы «семафора» чтобы ограничить потоки.
while IFS = читаем файл построчно и обрабатываем строки.
read -u 3 = ждем свободный слот «семафора», каждый поток блокируется до тех пор, пока не освободится место в «семафоре».
wait exec 3>&- = ждем завершение всех потоков
Что такое FIFO?
Представляем ебейшую очередь в магазине:
- Бабки встают в очередь
- Первым обслуживают ту бабку, что пришла первой
- Никто не может сказать — мне только спросить и пройти первым
Ну или на примере стопки книг:
Если ты складываешь книги в стопку и потом начинаешь снимать их, то ты будешь использовать LIFO (Last In, First Out).
Но если ты встал в очередь к кассе — это FIFO.
Думаю, ты понял, тут все просто.
Единственное отличие от cat, у нас получилось, что строчки выводятся в порядке завершения потока. Какой поток быстрее завершился тот и папа.
строка4
строка1
строка2
строка3
строка5
строка6
Ну и домашка тебе: сделай так, чтобы строчки выводились по порядку (также, как и в файле), но использовалась многопоточность.
Пользуйтесь, чо!








Комментарии