Saya ingin memproses banyak file dan karena saya sudah ada di sini sekelompok core saya ingin melakukannya secara paralel:
for i in *.myfiles; do do_something $i `derived_params $i` other_params; done
Saya tahu solusi Makefile tetapi perintah saya membutuhkan argumen dari daftar globbing shell. Apa yang saya temukan adalah:
> function pwait() {
> while [ $(jobs -p | wc -l) -ge $1 ]; do
> sleep 1
> done
> }
>
Untuk menggunakannya, yang harus dilakukan adalah meletakkan & setelah pekerjaan dan panggilan tunggu, parameter memberikan jumlah proses paralel:
> for i in *; do
> do_something $i &
> pwait 10
> done
Tetapi ini tidak bekerja dengan baik, misalnya saya mencobanya dengan misalnya untuk loop mengkonversi banyak file tetapi memberi saya kesalahan dan meninggalkan pekerjaan dibatalkan.
Saya tidak dapat percaya bahwa ini belum dilakukan karena diskusi di milis zsh sudah sangat tua sekarang. Jadi, apakah Anda tahu yang lebih baik?
bash
shell
zsh
parallel-processing
matematika
sumber
sumber
echo "DONE"
setelah loop yang dijalankan sebelum pekerjaan aktif tidak selesai. => Ini membuat saya berpikir bahwa pekerjaan tidak dilakukan.Jawaban:
Makefile adalah solusi yang bagus untuk masalah Anda. Anda bisa memprogram eksekusi paralel ini dalam sebuah shell, tetapi sulit, seperti yang Anda perhatikan. Implementasi paralel dari merek tidak hanya akan menangani pekerjaan awal dan mendeteksi pemutusannya, tetapi juga menangani penyeimbangan muatan, yang rumit.
Persyaratan untuk globbing bukanlah halangan: ada implementasi yang mendukungnya. GNU make, yang memiliki ekspansi wildcard seperti
$(wildcard *.c)
dan akses shell seperti$(shell mycommand)
(mencari fungsi dalam manual pembuatan GNU untuk informasi lebih lanjut). Ini defaultmake
di Linux, dan tersedia di sebagian besar sistem lain. Inilah kerangka Makefile yang bisa Anda sesuaikan dengan kebutuhan Anda:Jalankan sesuatu seperti
make -j4
mengeksekusi empat pekerjaan secara paralel, ataumake -j -l3
untuk menjaga rata-rata beban sekitar 3.sumber
Saya tidak yakin seperti apa argumen turunan Anda. Tetapi dengan GNU Parallel http: // www.gnu.org/software/parallel/ Anda dapat melakukan ini untuk menjalankan satu pekerjaan per cpu core:
Jika yang ingin Anda dapatkan hanyalah dengan mengubah .stension {.} Mungkin berguna:
Tonton video intro ke GNU Parallel di http://www.youtube.com/watch?v=OpaiGYxkSuQ
sumber
Tidakkah menggunakan perintah shell
wait
berfungsi untuk Anda?Loop Anda menjalankan suatu pekerjaan kemudian menunggu untuk itu, kemudian melakukan pekerjaan berikutnya. Jika hal di atas tidak bekerja untuk Anda, maka milik Anda mungkin bekerja lebih baik jika Anda pindah
pwait
setelahnyadone
.sumber
for
loop bersarang untuk membatasi itu:for file in *; do for i in {1..10}; do do_something "$i" & done; wait; done
(belum diuji) Itu harus dilakukan sepuluh sekaligus dan tunggu sampai semua sepuluh dari masing-masing kelompok dilakukan sebelum memulai sepuluh berikutnya. Loop Anda melakukan satu per satu waktu membuat&
moot. Lihat pertanyaan yang ditautkan oleh JRobert untuk opsi lain. Cari di Stack Overflow untuk pertanyaan lain yang mirip dengan pertanyaan Anda (dan yang itu).for i in *
. Dia harus melewati argumen ke loop dengan pipa atau sesuatu. Kemudian alih-alih loop internal Anda bisa menjalankan penghitung tambahan dan menjalankan"micro-"wait"-s"
setiap "$ ((i% 32))" -eq '0'wait
dengan loop counter dalam bekerja dengan baik untuk saya. Terima kasih!Mengapa belum ada yang menyebutkan xargs?
Dengan asumsi Anda memiliki tiga argumen,
Kalau tidak, gunakan pembatas (null berguna untuk itu):
EDIT: untuk yang di atas, setiap parameter harus dipisahkan oleh karakter nol, dan kemudian jumlah parameter harus ditentukan dengan xargs -n.
sumber
Saya mencoba beberapa jawaban. Mereka membuat skrip sedikit lebih rumit dari yang dibutuhkan. Idealnya menggunakan
parallel
atauxargs
akan lebih disukai tetapi jika operasi di dalam untuk loop rumit itu bisa bermasalah untuk membuat file garis besar dan panjang untuk memasok ke paralel. alih-alih kita bisa menggunakan sumber sebagai berikutJadi untuk solusi masalah Anda akan terlihat seperti
mendefinisikan melakukan sesuatu sebagai
do_something.sh
}
jalankan dengan
xarg
ataugnu parallel
Saya menganggap independensi fungsional dari iterasi untuk tersirat.
sumber