LINUX.ORG.RU

Параллельный запуск цепочки программ, обменивающихся текстовыми файлами

 ,


0

1

Есть набор унаследованных программ, которые обмениваются данными не через стандартный ввод/вывод, а через текстовые файлы. Лежат в одной папке, входом для первой является один файл с данными.

Алгоритм работы: 1) В папку с программами копируется бинарный файл с данными 2) Запускается цепочка программ, первая из которых считывает файл с данными, она генерирует один или несколько текстовых файлов, которые являются входами для других программ, те в свою очередь тоже пишут файлы, и так до последней программы.

Проблема в том, что необходимо параллельно обрабатывать несколько бинарных файлов с данными (в кроне). Если бы обмен шел через стандартный ввод/вывод, то проблем бы не было, для каждой цепочки был бы свой процесс. Но так как текстовые файлы общие, получится не пойми что, что к чему относится понять будет невозможно.

Использовать лок-файлы затруднительно и ненадежно на мой взгляд, так как много файлов и много процессов. Может генерировать какие-то изолированные песочницы?

Подскажите как решить такую проблему?

В зависимости от логики программ «песочницей» может быть просто отдельный каталог. Следует заметить, что не всегда параллельное исполнение задач в сумме быстрее последовательного.

Elyas ★★★★★
()

1. man 1 mktemp 2. /dev/stdin

arto ★★
()

Тут два вида параллельности:

1) запуск нескольких цепочек одновременно - тут может быть достаточно нескольких каталогов.

2) распараллелить цепочку, как это происходит в юниксовыми пайпами - для этого можно подсунуть обработчикам fifo вместо временных файлов и запускать параллельно.

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

Спасибо за ответ!

Пожалуй буду думать над отдельными каталогами. Будет некий эталонный каталог, и несколько его копий - так называемых каналов. Перед каждым запуском буду проверять не обновились ли бинарники и конфиги в эталонном каталоге, если обновились, то копировать их в канал и после этого запускать процесс.

flanker
() автор топика
Ответ на: комментарий от legolegs

Спасибо! А что значит распараллелить цепочку? У меня в рамках одной цепочки необходимо последовательное выполнение.

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

Перед каждым запуском буду проверять не обновились ли бинарники и конфиги в

Если они обновляются «снаружи», а при штатной работе неизменны, то можно не проверять и не копировать, а сделать симлинки.

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

Типичная конструкция типа

gunzip file.gz | grep abcd | tr x y | gzip > newfile.gz

выполняется параллельно, со скоростью самого медленного процесса, используются 4 процессора а работа с диском минимизируется. Это гораздо быстрее, чем последовательно распаковать и сохранить в файл1, потом файл1 грепать в файл2, результат tr сохранять в файл3 и уже т его сжимать в файл4.gz

Я не знаю, что у вас там за программы, но если они читают входные файлы последовательно и по мере работы, а не целиком в память, то описанное подведение можно получить даже, если программы не обучены работать в pipeline a|b.

legolegs ★★★★★
()

Можно раскидывать на несколько потоков. Первая программа плодит потомков, передает данные им в stdin и т.д. Можно сделать/найти отдельно программу, которая разбивает один поток на несколько. Например программа запускает двух потомков, ей в stdin приходит 1:first string\n2:second string\n и она раскидывает данные по номеру. Потомки делают тоже самое. Всё будет отлично, если не нужно, чтобы одна программа читала из двух потоков, хотя тут тоже как-нибудь можно извратиться.

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

Это гораздо быстрее, чем последовательно распаковать и сохранить в файл1, потом файл1 грепать в файл2, результат tr сохранять в файл3 и уже т его сжимать в файл4.gz

Помимо проблемы с tell,seek,mmap у пайпных операций есть весьма неочевидная, но обидная проблема: если что-то произойдёт, то всё надо начинать сначала. Да и статус о проблеме можно получить либо слева либо справа, а если пайпа два...

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

Можно через tee намутить:

$ cat test.txt | tee >(grep 1: | sed 's/^1://' > f1.txt) >(grep 2: | sed 's/^2://' > f2.txt)
1:file1
2:file2
1:file1_1
1:file1_2
2:file2_1
$ cat f1.txt
file1
file1_1
file1_2
$ cat f2.txt
file2
file2_1
Вот если два потока надо собрать - это будет проблема, хотя тоже можно что-нибудь придумать.

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

Нарисуй схему, какие программы какие данные как передают. Интересно.

crutch_master ★★★★★
()

Может генерировать какие-то изолированные песочницы?

chroot, особенно если программы нельзя менять и они используют захардкоженные пути/имена файлов, типа /tmp/data1.txt (тут будет затык если без чрута запустить более одного экземпляра программы)

futurama ★★★★★
()

Использовать лок-файлы затруднительно и ненадежно на мой взгляд, так как много файлов и много процессов. Может генерировать какие-то изолированные песочницы?

И вообще, у вас необоснованная идиосинкразия насчёт локов. Если вы сделаете скрипт с нужными операциями и в начале его повесите лок, то совершенно никаких проблем вызывать его параллельно нет.

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

Вот если два потока надо собрать - это будет проблема, хотя тоже можно что-нибудь придумать.

Нет никакой проблемы, mkfifo и вперёд. Можно через exec {MYNEWFD}, но не стоит. Единственная проблема - ромбы, когда поток раздвояем, а потом склеиваем - при разных скоростях работы из-за буферизации возможны дедлоки.

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

Проблема то у вас в чем? Почему не можете запускать последовательно? Какой объем данных и где самые критичные затраты времени?

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

Блин, по ходу я не умел пользоваться локами (фэйспалм.джпг). Надо так:

#!/bin/bash

lockfile -r 0 important.lock || exit 1

#Здесь алгоритм колбасит вызов программ

rm -f important.lock

Я не указыал exit 1 и думал какого художника у меня лок ничего не лочит. Вобщем локи тоже вариант, как и папки.

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