Dalam kode contoh di bawah ini, saya ingin memulihkan nilai kembali fungsi worker
. Bagaimana saya bisa melakukan ini? Di mana nilai ini disimpan?
Kode Contoh:
import multiprocessing
def worker(procnum):
'''worker function'''
print str(procnum) + ' represent!'
return procnum
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
print jobs
Keluaran:
0 represent!
1 represent!
2 represent!
3 represent!
4 represent!
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, stopped)>, <Process(Process-5, stopped)>]
Sepertinya saya tidak dapat menemukan atribut yang relevan pada objek yang disimpan jobs
.
multiprocessing.Queue
, daripada diManager
sini. MenggunakanManager
membutuhkan pemijahan proses yang sama sekali baru, yang berlebihan ketikaQueue
akan dilakukan.multiprocessing.Pool.map
untuk memproses daftar item pekerjaan Anda.args=(my_function_argument, )
. Perhatikan,
koma di sini! Atau Python akan mengeluh "argumen posisi hilang". Butuh waktu 10 menit untuk mencari tahu. Periksa juga penggunaan manual (di bawah bagian "kelas proses").Saya pikir pendekatan yang disarankan oleh @sega_sai adalah yang lebih baik. Tapi itu benar-benar membutuhkan contoh kode, jadi begini:
Yang akan mencetak nilai kembali:
Jika Anda terbiasa dengan
map
(Python 2 built-in) ini seharusnya tidak terlalu menantang. Kalau tidak, lihat tautan sega_Sai .Perhatikan betapa sedikit kode yang dibutuhkan. (Perhatikan juga bagaimana proses digunakan kembali).
sumber
getpid()
mengembalikan semua nilai yang sama? Saya menjalankan Python3pool.map
1.000.000 menggunakan lebih dari 10 proses, saya melihat paling banyak dua pids yang berbeda.pool.apply_async
: docs.python.org/3/library/…Contoh ini menunjukkan cara menggunakan daftar multiprosesing. Contoh instance untuk mengembalikan string dari sejumlah proses arbitrer:
Keluaran:
Solusi ini menggunakan lebih sedikit sumber daya daripada multiprocessing.Queue yang menggunakan
atau multiprocessing. SimpleQueue yang digunakan
Sangat instruktif untuk melihat sumber untuk masing-masing jenis ini.
sumber
Pipe
per proses vs satuQueue
untuk semua proses. Saya tidak tahu apakah itu menjadi lebih efisien dalam semua kasus.Untuk beberapa alasan, saya tidak dapat menemukan contoh umum tentang cara melakukan ini di
Queue
mana saja (bahkan contoh dokumen Python tidak menelurkan banyak proses), jadi inilah yang saya dapat kerjakan setelah 10 percobaan:Queue
adalah pemblokiran, antrian aman yang dapat Anda gunakan untuk menyimpan nilai kembali dari proses anak. Jadi, Anda harus melewati antrian untuk setiap proses. Sesuatu yang kurang jelas di sini adalah bahwa Anda harusget()
dari antrian sebelum Andajoin
yangProcess
es atau antrian mengisi dan blok segalanya.Pembaruan untuk mereka yang berorientasi objek (diuji dengan Python 3.4):
sumber
Untuk siapa pun yang mencari cara untuk mendapatkan nilai dari
Process
menggunakanQueue
:sumber
Queue
dari fungsi saya itu membiarkan saya lulusjoin()
queue.put(ret)
sebelum meneleponp.start()
? Dalam hal ini, utas pekerja akan menggantungqueue.get()
selamanya. Anda dapat meniru ini dengan menyalin cuplikan saya di atas saat berkomentarqueue.put(ret)
.queue.get()
harus terjadi sebelump.join()
. Sekarang berfungsi untuk saya.Tampaknya Anda harus menggunakan kelas multiprocessing.Pool sebagai gantinya dan menggunakan metode .apply () .apply_async (), map ()
http://docs.python.org/library/multiprocessing.html?highlight=pool#multiprocessing.pool.AsyncResult
sumber
Anda dapat menggunakan
exit
bawaan untuk mengatur kode keluar dari suatu proses. Itu dapat diperoleh dariexitcode
atribut proses:Keluaran:
sumber
The kerikil paket memiliki leveraging abstraksi yang bagus
multiprocessing.Pipe
yang membuat ini cukup mudah:Contoh dari: https://pythonhosted.org/Pebble/#concurrent-decorators
sumber
Pikir saya akan menyederhanakan contoh paling sederhana yang disalin dari atas, bekerja untuk saya di Py3.6. Paling sederhana adalah
multiprocessing.Pool
:Anda dapat mengatur jumlah proses di kumpulan dengan, misalnya
Pool(processes=5)
,. Namun standarnya adalah jumlah CPU, jadi biarkan kosong untuk tugas yang terikat CPU. (Tugas I / O-terikat sering sesuai dengan utas, karena utas sebagian besar menunggu sehingga dapat berbagi inti CPU.)Pool
Juga menerapkan optimasi chunking .(Perhatikan bahwa metode pekerja tidak dapat disarangkan dalam metode. Saya awalnya mendefinisikan metode pekerja saya di dalam metode yang membuat panggilan ke
pool.map
, untuk menjaga semuanya mandiri, tetapi kemudian proses tidak dapat mengimpornya, dan melemparkan "AttributeError : Tidak dapat mengasah objek lokal outer_method..inner_method ". Lebih lanjut di sini . Bisa di dalam kelas.)(Menghargai pertanyaan asli yang ditentukan
'represent!'
daripada mencetaktime.sleep()
, tetapi tanpa itu saya pikir beberapa kode berjalan bersamaan ketika tidak.)Py3
ProcessPoolExecutor
juga dua baris (.map
mengembalikan generator sehingga Anda perlulist()
):Dengan
Process
es polos :Gunakan
SimpleQueue
jika yang Anda butuhkan adalahput
danget
. Loop pertama memulai semua proses, sebelum yang kedua membuatqueue.get
panggilan pemblokiran . Saya tidak berpikir ada alasan untuk meneleponp.join()
juga.sumber
Solusi sederhana:
Keluaran:
sumber
Jika Anda menggunakan Python 3, Anda bisa menggunakan
concurrent.futures.ProcessPoolExecutor
abstraksi yang praktis:Keluaran:
sumber
Saya mengubah jawaban vartec sedikit karena saya perlu mendapatkan kode kesalahan dari fungsi. (Terima kasih vertec !!! ini trik yang luar biasa)
Ini juga dapat dilakukan dengan
manager.list
tetapi saya pikir lebih baik untuk memilikinya di dict dan menyimpan daftar di dalamnya. Dengan begitu, cara kita menjaga fungsi dan hasilnya karena kita tidak bisa memastikan urutan daftar yang akan diisi.sumber