Saya meneliti terlebih dahulu dan tidak dapat menemukan jawaban atas pertanyaan saya. Saya mencoba menjalankan banyak fungsi secara paralel dengan Python.
Saya punya sesuatu seperti ini:
files.py
import common #common is a util class that handles all the IO stuff
dir1 = 'C:\folder1'
dir2 = 'C:\folder2'
filename = 'test.txt'
addFiles = [25, 5, 15, 35, 45, 25, 5, 15, 35, 45]
def func1():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir1)
c.getFiles(dir1)
time.sleep(10)
c.removeFiles(addFiles[i], dir1)
c.getFiles(dir1)
def func2():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir2)
c.getFiles(dir2)
time.sleep(10)
c.removeFiles(addFiles[i], dir2)
c.getFiles(dir2)
Saya ingin memanggil func1 dan func2 dan menjalankannya pada waktu yang sama. Fungsi tidak berinteraksi satu sama lain atau pada objek yang sama. Sekarang saya harus menunggu func1 selesai sebelum func2 dimulai. Bagaimana saya melakukan sesuatu seperti di bawah ini:
process.py
from files import func1, func2
runBothFunc(func1(), func2())
Saya ingin dapat membuat kedua direktori pada waktu yang hampir bersamaan karena setiap menit saya menghitung berapa banyak file yang sedang dibuat. Jika direktori tidak ada di sana, itu akan membuang waktu saya.
Jawaban:
Anda bisa menggunakan
threading
ataumultiprocessing
.Karena kekhasan CPython ,
threading
tidak mungkin untuk mencapai paralelisme yang sebenarnya. Untuk alasan ini,multiprocessing
umumnya taruhan yang lebih baik.Berikut contoh lengkapnya:
Mekanisme memulai / menggabungkan proses anak dapat dengan mudah diringkas menjadi fungsi di sepanjang baris Anda
runBothFunc
:sumber
Ini dapat dilakukan dengan elegan dengan Ray , sebuah sistem yang memungkinkan Anda untuk dengan mudah memparalelkan dan mendistribusikan kode Python Anda.
Untuk memparalelkan contoh Anda, Anda perlu mendefinisikan fungsi Anda dengan
@ray.remote
dekorator, dan kemudian memanggilnya dengan.remote
.Jika Anda meneruskan argumen yang sama ke kedua fungsi dan argumennya besar, cara yang lebih efisien untuk melakukannya adalah dengan menggunakan
ray.put()
. Ini menghindari argumen besar untuk diserialkan dua kali dan untuk membuat dua salinan memori darinya:Jika
func1()
danfunc2()
mengembalikan hasil, Anda perlu menulis ulang kode sebagai berikut:Ada sejumlah keuntungan menggunakan Ray dibandingkan modul multiprosesing . Secara khusus, kode yang sama akan berjalan di satu mesin serta di sekumpulan mesin. Untuk lebih banyak keuntungan dari Ray lihat posting terkait ini .
sumber
Jika fungsi Anda terutama melakukan pekerjaan I / O (dan lebih sedikit pekerjaan CPU) dan Anda memiliki Python 3.2+, Anda dapat menggunakan ThreadPoolExecutor :
Jika fungsi Anda terutama melakukan pekerjaan CPU (dan lebih sedikit pekerjaan I / O) dan Anda memiliki Python 2.6+, Anda dapat menggunakan modul multiprosesing :
sumber
Jika Anda adalah pengguna windows dan menggunakan python 3, maka posting ini akan membantu Anda untuk melakukan pemrograman paralel di python. Ketika Anda menjalankan pemrograman kumpulan perpustakaan multiprosesing biasa, Anda akan mendapatkan kesalahan mengenai fungsi utama dalam program Anda. Ini karena fakta bahwa windows tidak memiliki fungsionalitas fork (). Posting di bawah ini memberikan solusi untuk masalah yang disebutkan.
http://python.6.x6.nabble.com/Multiprocessing-Pool-woes-td5047050.html
Karena saya menggunakan python 3, saya mengubah programnya sedikit seperti ini:
Setelah fungsi ini, kode masalah di atas juga sedikit berubah seperti ini:
Dan saya mendapatkan hasilnya sebagai:
Saya berpikir bahwa posting ini mungkin bermanfaat bagi beberapa pengguna windows.
sumber
Tidak ada cara untuk menjamin bahwa dua fungsi akan dijalankan secara sinkron satu sama lain yang sepertinya ingin Anda lakukan.
Hal terbaik yang dapat Anda lakukan adalah membagi fungsi menjadi beberapa langkah, lalu tunggu keduanya selesai pada titik sinkronisasi kritis menggunakan
Process.join
seperti jawaban @ aix yang menyebutkan.Ini lebih baik daripada
time.sleep(10)
karena Anda tidak dapat menjamin pengaturan waktu yang tepat. Dengan menunggu secara eksplisit, Anda mengatakan bahwa fungsi harus dilakukan dengan mengeksekusi langkah itu sebelum pindah ke langkah berikutnya, alih-alih mengasumsikan itu akan dilakukan dalam 10 md yang tidak dijamin berdasarkan apa lagi yang terjadi di mesin.sumber
Sepertinya Anda memiliki satu fungsi yang perlu Anda panggil pada dua parameter berbeda. Ini dapat dilakukan dengan elegan menggunakan kombinasi
concurrent.futures
danmap
dengan Python 3.2+Sekarang, jika operasi Anda terikat IO, Anda dapat menggunakan
ThreadPoolExecutor
seperti ini:Perhatikan bagaimana
map
digunakan di sini untukmap
fungsi Anda ke daftar argumen.Sekarang, Jika fungsi Anda terikat dengan CPU, maka Anda dapat menggunakan
ProcessPoolExecutor
Jika Anda tidak yakin, Anda dapat mencoba keduanya dan melihat mana yang memberi Anda hasil yang lebih baik.
Terakhir, jika Anda ingin mencetak hasil Anda, cukup lakukan ini:
sumber