Ini mungkin telah ditanyakan dalam konteks yang sama tetapi saya tidak dapat menemukan jawaban setelah sekitar 20 menit pencarian, jadi saya akan bertanya.
Saya telah menulis skrip Python (katakanlah: scriptA.py) dan skrip (katakanlah scriptB.py)
Di scriptB saya ingin memanggil scriptA beberapa kali dengan argumen yang berbeda, setiap kali membutuhkan waktu sekitar satu jam untuk dijalankan, (ini adalah script yang sangat besar, melakukan banyak hal .. jangan khawatir tentang itu) dan saya ingin dapat menjalankan scriptA dengan semua argumen yang berbeda secara bersamaan, tapi saya harus menunggu sampai SEMUAnya selesai sebelum melanjutkan; kode saya:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Saya ingin menjalankan semua subprocess.call()
pada waktu yang sama, dan kemudian menunggu sampai semuanya selesai, bagaimana saya harus melakukan ini?
Saya mencoba menggunakan threading seperti contoh di sini :
from threading import Thread
import subprocess
def call_script(args)
subprocess.call(args)
#run scriptA
t1 = Thread(target=call_script, args=(scriptA + argumentsA))
t2 = Thread(target=call_script, args=(scriptA + argumentsB))
t3 = Thread(target=call_script, args=(scriptA + argumentsC))
t1.start()
t2.start()
t3.start()
Tetapi menurut saya ini tidak benar.
Bagaimana saya tahu mereka semua telah selesai berlari sebelum pergi ke saya do_finish()
?
sumber
join
memblokir hingga thread menyelesaikan eksekusi. Anda harus menunggu semua utasnya. Jikat1
selesai dulu Anda akan mulai menunggut2
(yang mungkin sudah selesai dan Anda akan segera melanjutkan menunggut3
). Jikat1
membutuhkan waktu paling lama untuk dieksekusi, ketika Anda kembali dari keduanyat1
dant2
akan segera kembali tanpa memblokir.join
semacam melampirkan proses saat ini ke utas dan menunggu sampai selesai, dan jika t2 selesai sebelum t1 maka ketika t1 selesai itu akan memeriksa t2 selesai lihat bahwa itu benar, dan kemudian periksa t3..etc..etc .. dan kemudian hanya setelah semua selesai maka akan dilanjutkan. mengagumkan.Masukkan utas ke dalam daftar dan kemudian gunakan metode Gabung
sumber
for x in threads: x.join()
daripada menggunakan pemahaman daftarDi Python3, karena Python 3.2 ada pendekatan baru untuk mencapai hasil yang sama, yang secara pribadi saya lebih suka pembuatan utas tradisional / start / join, paket
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlMenggunakan
ThreadPoolExecutor
kode tersebut adalah:Output dari kode sebelumnya adalah seperti:
Salah satu keuntungannya adalah Anda dapat mengontrol pengaturan throughput pekerja bersamaan secara maksimal.
sumber
with
pernyataan dijalankan ketika semua tugas telah selesai.with
pernyataan dengan desain dalam kasus ini. Bagaimanapun, Anda selalu dapat membuka pertanyaan baru di SO dan memposting kode Anda sehingga kami dapat membantu Anda untuk mengetahui apa yang terjadi dalam kasus Anda.concurrent.futures.wait
fungsi, Anda dapat melihat contoh nyata di sini. Dokumen resmi: docs.python.org/3/library/…Saya lebih suka menggunakan pemahaman daftar berdasarkan daftar masukan:
sumber
for t in threads:t.start()
bukankah lebih baik?Anda dapat memiliki kelas seperti di bawah ini di mana Anda dapat menambahkan 'n' sejumlah fungsi atau console_scripts yang ingin Anda jalankan dalam passion paralel dan memulai eksekusi dan menunggu semua pekerjaan selesai ..
sumber
Dari
threading
dokumentasi modulJadi, untuk menangkap dua kasus tersebut ketika Anda tidak tertarik untuk menyimpan daftar utas yang Anda buat:
Dimana:
sumber
Mungkin, seperti itu
sumber
Saya baru saja menemukan masalah yang sama di mana saya harus menunggu semua utas yang dibuat menggunakan for loop. Saya baru saja mencoba potongan kode berikut Ini mungkin bukan solusi yang tepat tetapi saya pikir itu akan menjadi solusi yang sederhana untuk menguji:
sumber