Bạn có thể thử using multiple processes như thế này:
import multiprocessing as mp
def compute(j):
# compute a bunch of data
return data
def write(data):
# write data to disk
if __name__ == '__main__':
pool = mp.Pool()
for j in xrange(200):
pool.apply_async(compute, args=(j,), callback=write)
pool.close()
pool.join()
pool = mp.Pool()
sẽ tạo ra một hồ bơi của các quá trình lao động. Theo mặc định, số lượng công nhân bằng số lõi CPU mà máy của bạn có.
Mỗi hàng đợi pool.apply_async một nhiệm vụ được điều hành bởi một nhân viên trong nhóm quy trình công nhân. Khi một nhân viên có mặt, nó hoạt động compute(j)
. Khi công nhân trả về một giá trị, data
, một luồng trong quy trình chính chạy hàm gọi lại write(data)
, với data
là dữ liệu được trả về bởi người lao động.
Một số hãy cẩn thận:
- Các dữ liệu này phải được picklable, vì nó đã được truyền đạt từ quá trình lao động trở lại quá trình chính thông qua một Queue.
- Không đảm bảo rằng thứ tự mà người lao động hoàn thành nhiệm vụ giống như thứ tự mà tác vụ được gửi đến hồ bơi . Vì vậy, thứ tự dữ liệu được ghi vào đĩa có thể không tương ứng với
j
từ 0 đến 199. Một cách xung quanh vấn đề này sẽ ghi dữ liệu vào cơ sở dữ liệu sqlite (hoặc loại khác) với j
của các trường dữ liệu. Sau đó, khi bạn muốn đọc dữ liệu theo thứ tự, bạn có thể SELECT * FROM table ORDER BY j
.
Sử dụng nhiều quy trình sẽ tăng dung lượng bộ nhớ cần thiết khi dữ liệu được tạo bởi các quy trình công nhân và dữ liệu đang chờ ghi vào đĩa tích lũy trong Hàng đợi. Bạn có thể giảm dung lượng bộ nhớ cần thiết bằng cách sử dụng các mảng NumPy . Nếu điều đó là không thể, sau đó bạn có thể phải giảm bớt số của các quá trình:
pool = mp.Pool(processes=1)
Điều đó sẽ tạo ra một quá trình lao động (để chạy compute
), để lại quá trình chính để chạy write
. Vì compute
mất nhiều thời gian hơn write
, Hàng đợi sẽ không được sao lưu với nhiều hơn một đoạn dữ liệu được ghi vào đĩa.Tuy nhiên, bạn vẫn cần đủ bộ nhớ để tính toán trên một đoạn dữ liệu trong khi viết một đoạn dữ liệu khác nhau của vào đĩa.
Nếu bạn không có đủ bộ nhớ để thực hiện đồng thời, bạn không có lựa chọn nào - mã ban đầu của bạn, chạy theo thứ tự compute
và write
, là cách duy nhất.
Tại sao quá trình sử dụng và ghi vào một tập tin chỉ là IO và không ảnh hưởng đến GIL? –
2-5 phút đang được chi cho tính toán, so với chỉ 1 phút IO. Nếu máy có nhiều lõi, bạn có thể tăng tốc độ tính toán bằng cách truyền bá công việc giữa các lõi. – unutbu
Không sao, bạn đúng. Lấy làm tiếc. –