2015-06-06 1 views
5

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

Я запускаю программу с использованием gnu-параллели, которая могла бы производить тонны (от GB до 1 ТБ, которые сейчас трудно понять) вывода, отформатированного для базы данных на mySQL.

Я понял, что я могу открыть два терминала: терминал 1 получает что-то вроде:

find . -type f -name "*.h" | parallel --jobs 12 'cprogram {}' > /home/pipe 

Где труба является ФИФО производится с mkfifo.

На втором терминале я запускаю команду, подобную этой:

mysql DataBaseName -e "LOAD DATA LOCAL INFILE '/home/pipe' INTO TABLE tableName"; 

Он работает ...

Но это Janky ... Если я правильно понимаю, есть EOF генерируется, когда первый процесс заканчивается, заставляя трубу закрываться.

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

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

+0

Почему вы специально хотите использовать именованный канал для этого вместо обычного файла? – jangler

+0

@jangler Хороший вопрос. Выходной сигнал может стать ТБ, а время чтения/записи на диск, а затем в БД может быть другой избегаемой бутылочной шейкой. Плюс ресурсы хранилища являются проблемой, так как я не могу предположить, что я смогу запустить это на большой мощной машине, поскольку я могу быть на сайте клиента и в сжатые сроки. – wbg

ответ

3

Если я правильно понял, возникает EOF, когда первый процесс заканчивается, заставляя трубку закрываться.

Сорт. Это немного больше, чем это - технически некорректно говорить, что труба закрывается, как только заканчивается первый процесс.

Вместо этого трубы и FIFO возвращают EOF, когда в трубе больше нет данных, и он не открывается для записи каким-либо процессом.

Обычно это разрешается, когда процесс чтения открывает FIFO как для чтения, так и для записи, хотя он никогда не будет писать - например, сервер, который принимает локальные клиенты, читает из FIFO, может открыть FIFO для чтение и запись, так что, когда нет активных клиентов, сервер не должен иметь дело со специальным случаем EOF. Это «стандартный» способ справиться с этим, как описано в Расширенное программирование в среде UNIX в главе о механизмах МПК.

В вашем случае это невозможно, потому что у вас нет постоянного процесса, который продолжает работать (т. Е. У вас нет эквивалента серверного процесса). Вам в основном нужен какой-то «постоянный писатель», т. Е. Процесс, который поддерживает канал, открытый для записи во время разных итераций.

Одно из решений, о котором я могу думать, - это cat стандартный ввод в FIFO в фоновом режиме. Это гарантирует, что cat открывает FIFO для записи, поэтому всегда есть активный писатель, но, сохраняя его в фоновом режиме, вы фактически не подаете его на вход и никогда не записываете в FIFO.Просто имейте в виду, что работа будет прекращена (но не завершена) оболочкой, как только cat попытается прочитать с stdin (процессы, выполняемые в фоновом процессе, обычно отправляются SIGTTIN и останавливаются, когда они пытаются читать с stdin, потому что они не имеют управляющего терминала до тех пор, пока они не будут выведены на передний план). Во всяком случае, до тех пор, пока вы не будете подавать какие-либо данные, вы добры - процесс находится в остановленном состоянии, но FIFO все еще открыт для записи. Вы никогда не увидите EOF на трубе, пока фоновое задание не будет завершено.

Так, короче говоря, вы:

  1. Создание FIFO: mkfifo /home/pipe
  2. Начать фоновое задание, которая открывает FIFO для записи: cat >/home/pipe &
  3. Запуск ваших программ, однако вы хотите, со сколькими итераций, которые вы хотите. Игнорируйте сообщение оболочки об остановленном фоновом задании. Вы можете просто оставить это так, поскольку труба все еще открыта для записи, даже если задание остановлено.
  4. Когда вы закончите, убейте фон cat, либо доставив его на передний план, либо отправив его SIGINT (обычно, Ctrl + C) или с kill PID.

Обратите внимание, что при этом процесс чтения (mysql в этом случае) никогда не узнает, когда вход окончен. Он всегда будет блокировать больше ввода, если только вы не убьете фон cat, прежде чем убить mysql.

+1

Отличный ответ. Он охватывает мой вопрос, имеет ссылку на неочевидный документ и исправляет мое недоразумение. Приветствия! – wbg

+1

@ wbg Рад, что я мог помочь. Если у вас есть время и энергия, я настоятельно рекомендую читать * Расширенное программирование в среде UNIX * - вы подробно изучите этот материал. Это стоит прочитать :) –

 Смежные вопросы

  • Нет связанных вопросов^_^