Краще знайти Unix при паралельній обробці?


43

find(1)Утиліта unix дуже корисна, що дозволяє мені виконувати дії над багатьма файлами, які відповідають певним специфікаціям, наприклад

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

Вищезазначене може запускати скрипт або інструмент над кожним XML-файлом у певному каталозі.

Скажімо, мій сценарій / програма займає багато процесорного часу, і у мене є 8 процесорів. Було б непогано обробити до 8 файлів одночасно.

GNU make дозволяє паралельно обробляти завдання з -jпрапором, але find, схоже, не має такої функціональності. Чи існує альтернативний загальний метод планування робочих місць для підходу до цього?

Відповіді:


65

xargsз -Pопцією (кількість процесів). Скажіть, що я хотів стиснути всі логіни у каталозі на 4-процесорній машині:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

Ви також можете сказати -n <number>про максимальну кількість робочих одиниць за процес. Так що скажіть, у мене було 2500 файлів, і я сказав:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

Це запустило б 4 bzip2процеси, кожен з яких по 500 файлів, а потім, коли перший закінчив інший, буде запущено останні 500 файлів.

Не впевнений, чому використовується попередня відповідь, xargs і у make вас є два паралельних двигуна!


7
Що стосується find / xargs, будьте обережні: знаходьте за замовчуванням нові рядки як розділювачі виводу, а xargs за замовчуванням для будь-якого пробілу як роздільники введення. Для безпечності використовуйте -0 для обох, або переключіться на паралельний параметр GNU, який за замовчуванням використовує нові рядки як роздільники введення (відповідність результату пошуку).
ефеміент

1
Ух, дивовижно! Я щойно перевірив, і це правда, у xargs є -Pваріант!
ПП.

Обережно використовуйте xargs -P- у нього ніколи не виправлена ​​помилка видалення виходу (на відміну від parallelкожного разу, коли трапляються 2 нитки, щоб отримати вихід у той самий точний момент ...
Влад,

34

Паралель GNU теж може допомогти.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

Зауважте, що без -j8аргументу parallelза замовчуванням кількість ядер на вашій машині :-)


6

Не потрібно «виправляти» find- використовуйте makeсебе для вирішення паралелізму.

Попросіть ваш процес створити файл журналу чи якийсь інший вихідний файл, а потім використовуйте Makefile так:

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

і посилається таким чином:

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

Ще краще, якщо ви гарантуєте, що вихідний файл створюється лише після успішного завершення процесу Java, ви можете скористатися makeобробкою залежностей, щоб переконатися, що наступного разу обробляються лише необроблені файли.


1
Сподіваємось, у цих іменах немає пробілів та інших "цікавих" символів; Make не справляється з цими дуже елегантно.
ефеміент

Відмінна ідея! Ніколи не думав використовувати подібні файли.
oscfri

3

Find має паралельну опцію, яку можна використовувати безпосередньо, використовуючи символ "+"; не потрібно xargs. Поєднуючи його з грепом, він може швидко прорізати ваше дерево, шукаючи сірники. Наприклад, якщо я шукаю всі файли в моєму каталозі джерел, що містять рядок 'foo', я можу викликати
find sources -type f -exec grep -H foo {} +


12
Читаючи посібник з пошуку, ви можете побачити, що -exec command +синтаксис не запускає його паралельно, а об'єднує багато файлів разом і одночасно запускає команду з кількома файлами як аргументи. Буває, що греп може паралельно переглядати свої цілі.
Gyscos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.