Как использовать параллельное выполнение в скрипте оболочки? - PullRequest
19 голосов
/ 07 мая 2010

У меня есть сценарий оболочки C, который делает что-то вроде этого:

#!/bin/csh
gcc example.c -o ex
gcc combine.c -o combine
ex file1 r1     <-- 1
ex file2 r2     <-- 2
ex file3 r3     <-- 3
#... many more like the above
combine r1 r2 r3 final
\rm r1 r2 r3

Есть ли способ, как я могу сделать так, чтобы линии 1, 2 и 3 работали в параллельно вместо одной за другой?

Ответы [ 7 ]

13 голосов
/ 07 мая 2010

Преобразуйте это в Makefile с соответствующими зависимостями. Затем вы можете использовать make -j, чтобы Make запускал все возможное параллельно.

Обратите внимание, что все отступы в Makefile должны быть табуляцией. TAB показывает Make, где находятся команды для запуска.

Также обратите внимание, что этот Makefile теперь использует расширения GNU Make (функции подстановки и подстановки).

Это может выглядеть так:

export PATH := .:${PATH}

FILES=$(wildcard file*)
RFILES=$(subst file,r,${FILES})

final: combine ${RFILES}
    combine ${RFILES} final
    rm ${RFILES}

ex: example.c

combine: combine.c

r%: file% ex
    ex $< $@
8 голосов
/ 07 мая 2010

В bash я бы сделал;

ex file1 r1  &
ex file2 r2  &
ex file3 r3  &
wait
... continue with script...

и порождайте их для параллельной работы. Вы можете проверить этот поток SO для другого примера.

5 голосов
/ 07 мая 2010
#!/bin/bash

gcc example.c -o ex
gcc combine.c -o combine

# Call 'ex' 3 times in "parallel"
for i in {1..3}; do
  ex file${i} r${i} &
done

#Wait for all background processes to finish
wait

# Combine & remove
combine r1 r2 r3 final
rm r1 r2 r3

Я немного изменил код, чтобы использовать расширение скобок {1..3} вместо жесткого кодирования чисел, поскольку я только что понял, что вы сказали, что файлов гораздо больше, чем просто 3. Расширение скобок делает масштабирование до больших чисел тривиальным, заменяя '3' внутри фигурных скобок на любой номер, который вам нужен.

3 голосов
/ 07 мая 2010

вы можете использовать CMD & и ждать после

#!/bin/csh
echo start
sleep 1 &
sleep 1 &
sleep 1 &
wait
echo ok

тест:

$ time ./csh.sh 
start
[1] 11535
[2] 11536
[3] 11537
[3]    Done                   sleep 1
[2]  - Done                   sleep 1
[1]  + Done                   sleep 1
ok

real    0m1.008s
user    0m0.004s
sys 0m0.008s
0 голосов
/ 23 марта 2015

xargs может сделать это:

seq 1 3 | xargs -n 1 -P 0 -I % ex file% r%

-n 1 для «одной строки на вход», -P для «параллельной работы каждой строки»

0 голосов
/ 12 февраля 2011

Вы можете использовать nohup ex:

nohup ex file1 r1 &    
nohup ex file2 r2 &
nohup ex file3 r3 &
0 голосов
/ 11 июня 2010

GNU Parallel сделает это примерно так:

seq 1 3 | parallel ex file{} r{}

В зависимости от того, как 'ex' и 'комбинируют' работу, вы можете даже сделать:

seq 1 3 | parallel ex file{} | combine

Узнайте больше о GNU Parallel, просмотрев http://www.youtube.com/watch?v=LlXDtd_pRaY

...