Saya ingin menggunakan array numpy dalam memori bersama untuk digunakan dengan modul multiprocessing. Kesulitannya adalah menggunakannya seperti array numpy, dan bukan hanya sebagai array ctypes.
from multiprocessing import Process, Array
import scipy
def f(a):
a[0] = -a[0]
if __name__ == '__main__':
# Create the array
N = int(10)
unshared_arr = scipy.rand(N)
arr = Array('d', unshared_arr)
print "Originally, the first two elements of arr = %s"%(arr[:2])
# Create, start, and finish the child processes
p = Process(target=f, args=(arr,))
p.start()
p.join()
# Printing out the changed values
print "Now, the first two elements of arr = %s"%arr[:2]
Ini menghasilkan keluaran seperti:
Originally, the first two elements of arr = [0.3518653236697369, 0.517794725524976]
Now, the first two elements of arr = [-0.3518653236697369, 0.517794725524976]
Array dapat diakses dengan cara ctypes, misalnya arr[i]
masuk akal. Namun, ini bukan array numpy, dan saya tidak dapat melakukan operasi seperti -1*arr
, atau arr.sum()
. Saya kira solusinya adalah mengubah array ctypes menjadi array numpy. Namun (selain tidak dapat membuat ini berfungsi), saya tidak percaya itu akan dibagikan lagi.
Sepertinya akan ada solusi standar untuk apa yang harus menjadi masalah bersama.
python
numpy
multiprocessing
shared
Ian Langmore
sumber
sumber
subprocess
daripadamultiprocessing
.Jawaban:
Untuk menambah jawaban @ unutbu (tidak tersedia lagi) dan @Henry Gomersall. Anda dapat menggunakan
shared_arr.get_lock()
untuk menyinkronkan akses bila diperlukan:Contoh
Jika Anda tidak memerlukan akses tersinkronisasi atau Anda membuat kunci sendiri, maka
mp.Array()
itu tidak perlu. Anda bisa menggunakanmp.sharedctypes.RawArray
dalam kasus ini.sumber
count
kenumpy.frombuffer()
. Anda dapat mencoba melakukannya pada tingkat yang lebih rendah dengan menggunakanmmap
atau sesuatu sepertiposix_ipc
secara langsung untuk mengimplementasikan ukuran yang dapat diubah ukurannya (mungkin melibatkan penyalinan saat mengubah ukuran) analog RawArray (atau mencari perpustakaan yang ada). Atau jika tugas Anda memungkinkan: salin data menjadi beberapa bagian (jika Anda tidak membutuhkan semuanya sekaligus). "Bagaimana mengubah ukuran memori bersama" adalah pertanyaan terpisah yang bagus.Pool()
menentukan jumlah proses (jumlah inti CPU yang tersedia digunakan secara default).M
adalah berapa kalif()
fungsi dipanggil.The
Array
objek memilikiget_obj()
metode yang terkait dengan itu, yang mengembalikan ctypes array yang yang menyajikan antarmuka penyangga. Saya pikir berikut ini harus bekerja ...Saat dijalankan, ini mencetak elemen pertama yang
a
sekarang menjadi 10.0, menampilkana
danb
hanya dua tampilan ke dalam memori yang sama.Untuk memastikan itu masih multiprosesor aman, saya yakin Anda harus menggunakan metode
acquire
danrelease
yang ada padaArray
objeka
, dan kunci bawaannya untuk memastikan semuanya aman diakses (meskipun saya bukan ahli dalam modul multiprosesor).sumber
mp.Array
.Meskipun jawaban yang sudah diberikan sudah bagus, ada solusi yang jauh lebih mudah untuk masalah ini asalkan dua syarat terpenuhi:
Dalam hal ini Anda tidak perlu mengutak-atik variabel yang dibagikan secara eksplisit, karena proses anak akan dibuat menggunakan garpu. Anak bercabang secara otomatis membagikan ruang memori orang tuanya. Dalam konteks multiprocessing Python, ini berarti ia berbagi semua variabel tingkat modul ; perhatikan bahwa ini tidak berlaku untuk argumen yang Anda teruskan secara eksplisit ke proses anak Anda atau ke fungsi yang Anda panggil
multiprocessing.Pool
atau lebih.Contoh sederhana:
sumber
Saya telah menulis modul python kecil yang menggunakan memori bersama POSIX untuk berbagi array numpy antara interpreter python. Mungkin Anda akan menemukannya berguna.
https://pypi.python.org/pypi/SharedArray
Begini cara kerjanya:
sumber
Anda dapat menggunakan
sharedmem
modul: https://bitbucket.org/cleemesser/numpy-sharedmemInilah kode asli Anda, kali ini menggunakan memori bersama yang berperilaku seperti array NumPy (perhatikan pernyataan terakhir tambahan yang memanggil
sum()
fungsi NumPy ):sumber