Multi-Threading / Forking dalam skrip bash

9

Saya telah menulis skrip bash yang dalam format berikut:

#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"

rm -f $inFile $outFile

while read line
do

    -- Block of Commands

done < "$inFile"

end=$(date +%s)

runtime=$((end-start))

echo "Program has finished execution in $runtime seconds."

The whileLoop akan membaca dari $inFile, melakukan beberapa aktivitas di baris dan membuang hasil di $outFile.

Karena $inFilepanjangnya 3500+ baris, skrip akan membutuhkan 6-7 jam untuk mengeksekusi sepenuhnya. Untuk meminimalkan waktu ini, saya berencana menggunakan multi-threading atau forking dalam skrip ini. Jika saya membuat 8 proses anak, 8 baris dari $inFileakan diproses secara bersamaan.

Bagaimana ini bisa dilakukan?

Mandar Shinde
sumber
Berhati-hatilah: skrip yang berbeda perlu menulis ke file outfile yang berbeda . Juga skrip Anda sebagai tertulis menghapus file input sebagai tindakan pertama!
pjc50

Jawaban:

10

GNUparallel dibuat hanya untuk hal semacam ini. Anda dapat menjalankan skrip berkali-kali sekaligus, dengan data berbeda dari input Anda yang disalurkan untuk masing-masing:

cat input.txt | parallel --pipe your-script.sh

Secara default akan memunculkan proses sesuai dengan jumlah prosesor pada sistem Anda, tetapi Anda dapat menyesuaikannya dengan -j N.

Trik yang sangat rapi adalah fitur pembungkus shebang. Jika Anda mengubah baris pertama skrip Bash Anda menjadi:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash

dan memberi makan data pada input standar maka semuanya akan terjadi secara otomatis. Ini kurang berguna ketika Anda memiliki kode pembersihan yang harus dijalankan di akhir, yang mungkin Anda lakukan.

Ada beberapa hal yang perlu diperhatikan. Salah satunya adalah itu akan memotong input Anda menjadi potongan berurutan dan menggunakannya satu per satu - tidak memotong garis. Yang lain adalah bahwa potongan-potongan itu dibagi berdasarkan ukuran, tanpa memperhatikan berapa banyak catatan yang ada. Anda dapat menggunakan --block Nuntuk mengatur ukuran blok yang berbeda dalam byte. Dalam kasus Anda, tidak boleh lebih dari seperdelapan ukuran file. File Anda terdengar seperti itu mungkin cukup kecil untuk berakhir semua dalam satu blok jika tidak, yang akan mengalahkan tujuannya.

Ada banyak opsi untuk kasus penggunaan tertentu yang berbeda, tetapi tutorialnya cukup baik. Opsi yang mungkin juga menarik bagi Anda termasuk --round-robindan --group.

Michael Homer
sumber
1
Apakah Anda menguji garis shebang itu? Shebangs dengan banyak argumen tidak dapat diport. Di Linux, #!a b cakan menghasilkan ["b c"], sedangkan pada beberapa sistem lain, itu akan menghasilkan ["b", "c"].
nyuszika7h
1
Ini memunculkan kembali argumennya sendiri ketika digunakan dengan cara ini (jika tidak, opsi tidak akan banyak digunakan).
Michael Homer
@MichaelHomer perlu saya gunakan GNU paralleluntuk memo halaman HTML. Bisakah Anda membuka utas ini unix.stackexchange.com/questions/277609/…
Swatesh Pakhare