Если я правильно понял, возникает EOF, когда первый процесс заканчивается, заставляя трубку закрываться.
Сорт. Это немного больше, чем это - технически некорректно говорить, что труба закрывается, как только заканчивается первый процесс.
Вместо этого трубы и FIFO возвращают EOF, когда в трубе больше нет данных, и он не открывается для записи каким-либо процессом.
Обычно это разрешается, когда процесс чтения открывает FIFO как для чтения, так и для записи, хотя он никогда не будет писать - например, сервер, который принимает локальные клиенты, читает из FIFO, может открыть FIFO для чтение и запись, так что, когда нет активных клиентов, сервер не должен иметь дело со специальным случаем EOF. Это «стандартный» способ справиться с этим, как описано в Расширенное программирование в среде UNIX в главе о механизмах МПК.
В вашем случае это невозможно, потому что у вас нет постоянного процесса, который продолжает работать (т. Е. У вас нет эквивалента серверного процесса). Вам в основном нужен какой-то «постоянный писатель», т. Е. Процесс, который поддерживает канал, открытый для записи во время разных итераций.
Одно из решений, о котором я могу думать, - это cat
стандартный ввод в FIFO в фоновом режиме. Это гарантирует, что cat
открывает FIFO для записи, поэтому всегда есть активный писатель, но, сохраняя его в фоновом режиме, вы фактически не подаете его на вход и никогда не записываете в FIFO.Просто имейте в виду, что работа будет прекращена (но не завершена) оболочкой, как только cat
попытается прочитать с stdin
(процессы, выполняемые в фоновом процессе, обычно отправляются SIGTTIN и останавливаются, когда они пытаются читать с stdin
, потому что они не имеют управляющего терминала до тех пор, пока они не будут выведены на передний план). Во всяком случае, до тех пор, пока вы не будете подавать какие-либо данные, вы добры - процесс находится в остановленном состоянии, но FIFO все еще открыт для записи. Вы никогда не увидите EOF на трубе, пока фоновое задание не будет завершено.
Так, короче говоря, вы:
- Создание FIFO:
mkfifo /home/pipe
- Начать фоновое задание, которая открывает FIFO для записи:
cat >/home/pipe &
- Запуск ваших программ, однако вы хотите, со сколькими итераций, которые вы хотите. Игнорируйте сообщение оболочки об остановленном фоновом задании. Вы можете просто оставить это так, поскольку труба все еще открыта для записи, даже если задание остановлено.
- Когда вы закончите, убейте фон
cat
, либо доставив его на передний план, либо отправив его SIGINT (обычно, Ctrl + C) или с kill PID
.
Обратите внимание, что при этом процесс чтения (mysql в этом случае) никогда не узнает, когда вход окончен. Он всегда будет блокировать больше ввода, если только вы не убьете фон cat
, прежде чем убить mysql.
Почему вы специально хотите использовать именованный канал для этого вместо обычного файла? – jangler
@jangler Хороший вопрос. Выходной сигнал может стать ТБ, а время чтения/записи на диск, а затем в БД может быть другой избегаемой бутылочной шейкой. Плюс ресурсы хранилища являются проблемой, так как я не могу предположить, что я смогу запустить это на большой мощной машине, поскольку я могу быть на сайте клиента и в сжатые сроки. – wbg