LINUX.ORG.RU

[bash] работа с потоками

 


0

0

В скрипте есть конструкция вида:

while : ; do
        $(cat in_fifo);
done
Куда через именованный канал подсовывают куски кода запускаемые в новом потоке. Хочется чтобы цикл разрывался после того как все эти потоки будут завершены. Как можно к этому подойти? Единственное что мне приходит в голову, это создавать вместе с каждым потоком файл в специальном месте и полагать условием новой итерации цикла наличие хотя бы одного такого файла. Нет ли варианта по приличнее?

★★★★★

Ответ на: комментарий от tailgunner

В канал запихивают куски вида

dosomething &

Таким образом этих something'ов может быть уйма. Нужно чтобы по завершению всех something'ов цикл тоже как-то завершился.

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

> В канал запихивают куски вида

А по условию задачи входом служит именно FIFO? Если вход - обычный pipe, то задача решается тривиально, а в случае FIFO придется делать маркер "конец программы".

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

Именно. Вот я и думаю как лучше разрывать этот цикл когда все команды закончатся. Ведь большую часть времени он слушает канал. То есть своевременно разорвать его может только команда из канала (например break). Но как эту команду сгенерировать? Как вообще определить что все запущенные команды исполнились?

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

> То есть своевременно разорвать его может только команда из канала (например break).

Какой кошмар. В чем вообще цель этого скрипта? По-моему, он вообще нафиг не нужен. И повторю вопрос - почему FIFO, а не pipe?

> Но как эту команду сгенерировать?

Так же, как ты все остальные генеришь.

> Как вообще определить что все запущенные команды исполнились?

wait

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

>Какой кошмар. В чем вообще цель этого скрипта? По-моему, он вообще нафиг не нужен. И повторю вопрос - почему FIFO, а не pipe?

По сути это интерфейс для взаимодействия с запущенным где-то в фоне башем. Поскольку один баш от другого в первую очередь отличается определёнными в нём переменными и функциями то предполагается что на время пока в нём ничего не исполняют его окружение дампится и лежит файлом пока его не пнут. Когда пинают из дампа восстанавливают окружение и выполняют в нём пользовательские команды. Задача в том чтобы понять когда окружение можно сбросить на диск.

>wait

wait будет ждать когда завершится бесконечный цикл.

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

> окружение дампится и лежит файлом пока его не пнут. Когда пинают из дампа восстанавливают окружение и выполняют в нём пользовательские команды. Задача в том чтобы понять когда окружение можно сбросить на диск.

Я таки не понимаю, чем обычный цикл асинхронного запуска команд не подходит, что надо городить FIFO и второй баш. Видимо, задача для меня слишком сложна.

> wait будет ждать когда завершится бесконечный цикл.

Да мы еще и на разных языках говорим %)

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

>Да мы еще и на разных языках говорим %)

Попробуй привести пример кода. Может быть станет понятнее.

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

>> Да мы еще и на разных языках говорим %)

> Попробуй привести пример кода.

Ы?

while :; do
 cmd=$(cat in_fifo)
 if [ "$cmd" == "EOF" ]; then
   break
 else
   eval $cmd
 fi
done
wait

> Может быть станет понятнее.

Мне точно не станет %)

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

Понял. Я не вполне ясно изложил задачу. Из бесконечного цикла нельзя выходить до того как выполнятся все запущенные команды. Иными словами пользователь закидывает в канал sleep 60 & и в течении всего времени выполнения этой команды может закинуть туда ещё что-нибудь. Вариант который ты предложил был бы прекрасен если бы я ещё знал как заставить последний завершившийся поток послать EOF в in_fifo.

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

> если бы я ещё знал как заставить последний завершившийся поток послать EOF в in_fifo.

Сдался тебе этот FIFO. Почему нельзя выводить команды на stdout, а этим скриптом читать с stdin? Тогда всё вообще тривиально, даже посылка "EOF" не нужна.

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

Он сдался мне по двум причинам. Во-первых я просто слабо представляю как заставить слушать stdin (что было бы хорошо исправить), а во-вторых я слабо представляю как что-либо направить на стандартный ввод уже запущенной программы (что тоже очень плохо). Иными словами я просто не умею иначе.

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

> Во-первых я просто слабо представляю как заставить слушать stdin (что было бы хорошо исправить)

Ы? Вот твоя задача, если считать, что someprog выдает команды на стандартный вывод:

./someprog | (while read c; do; eval $c & done; wait)

> я слабо представляю как что-либо направить на стандартный ввод уже запущенной программы

Если тебе это действительно нужно, ты попал :)

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

cat ./someprog

#!/bin/bash

while : ; do
    cat in_fifo
done

:^)

А вообще то что ты предлагаешь опять таки не совсем то. Мне нужно чтобы перестала слушать внешние команды после того как завершится выполнение всех полученных извне команд. Иными словами что-то вроде:

./someprog | (while read c; do; eval $c & done & magic_wait)

Где magic_wait это такой wait который дожидается завершения не вообще всех запущенных подпрограмм, а всех запущенных подпрограмм кроме самого бесконечного цикла.

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

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

Ч0рт, я пас. Просто пойми, что тебе это не нужно.

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