2017-11-16 22 views
10

Tôi đang sử dụng đa xử lý của Python.Đồ dùng chung để phân phối các tác vụ giữa các quy trình.multiprocessing.Pool tạo ra nhiều quy trình hơn chỉ được yêu cầu trên Google Cloud

Các trường hợp đơn giản làm việc như mong đợi:

from multiprocessing import Pool 

def evaluate: 
    do_something() 

pool = Pool(processes=N) 
for task in tasks: 
    pool.apply_async(evaluate, (data,)) 

N quá trình được sinh ra, và họ tiếp tục làm việc thông qua các nhiệm vụ mà tôi vượt qua thành apply_async. Bây giờ, tôi có một trường hợp khác, nơi tôi có nhiều đối tượng rất phức tạp khác nhau mà mỗi đối tượng cần phải thực hiện hoạt động nặng tính toán. Ban đầu, tôi cho phép mỗi đối tượng tạo đa xử lý riêng của mình.Theo yêu cầu tại thời điểm nó hoàn thành công việc, nhưng cuối cùng tôi chạy vào OSError vì có quá nhiều tệp đang mở, mặc dù tôi đã giả định rằng các hồ bơi sẽ bị thu gom rác sau khi sử dụng.

Dù sao đi nữa, tôi quyết định nó sẽ là thích hợp hơn anyway cho mỗi một trong các đối tượng phức tạp để chia sẻ Pool tương tự cho tính toán:

from multiprocessing import Pool 

def evaluate: 
    do_something() 

pool = Pool(processes=N) 

class ComplexClass: 

    def work: 
     for task in tasks: 
      self.pool.apply_async(evaluate, (data,)) 

objects = [ComplexClass() for i in range(50)] 

for complex in objects: 
    complex.pool = pool 


while True: 
    for complex in objects: 
     complex.work() 

Bây giờ, khi tôi chạy trên một trong những máy tính của tôi (OS X , Python = 3.4), nó hoạt động như mong đợi. Các tiến trình N được sinh ra, và mỗi đối tượng phức tạp phân phối các nhiệm vụ của chúng trong mỗi chúng. Tuy nhiên, khi tôi chạy nó trên một máy khác (ví dụ của Google Cloud chạy Ubuntu, Python = 3.5), nó sinh ra một số lượng lớn các quy trình (>> N) và toàn bộ chương trình bị ngừng lại do tranh chấp.

Nếu tôi kiểm tra các hồ bơi để biết thêm thông tin:

import random 
random_object = random.sample(objects, 1) 
print (random_object.pool.processes) 

>>> N 

Tất cả mọi thứ có vẻ đúng. Nhưng rõ ràng là không. Bất kỳ ý tưởng gì có thể xảy ra?

CẬP NHẬT

tôi đã thêm một số đăng nhập bổ sung. Tôi đặt kích thước hồ bơi thành 1 để đơn giản. Trong hồ bơi, khi một nhiệm vụ đang được hoàn thành, tôi in current_process() từ mô-đun đa xử lý, cũng như pid của tác vụ bằng cách sử dụng os.getpid(). Nó là kết quả trong một cái gì đó như thế này:

<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
... 

Một lần nữa, nhìn vào thực tế hoạt động sử dụng htop, tôi nhìn thấy nhiều quá trình (một cho mỗi đối tượng chia sẻ hồ đa) tất cả các CPU tiêu thụ chu kỳ như điều này xảy ra, dẫn đến quá nhiều hệ điều hành tranh luận rằng tiến bộ là rất chậm. 5122 dường như là quá trình cha mẹ.

+0

bạn có thể thêm lệnh gọi 'multiprocessing.log_to_stderr (logging.DEBUG)', nhật ký khác sẽ được in để hỗ trợ gỡ lỗi. – georgexsh

+0

@georgexsh Tôi đã thêm điều này để hỗ trợ gỡ lỗi, nhưng đầu ra duy nhất tôi thấy nó: [DEBUG/MainProcess] bắt đầu nghe và luồng để gửi xử lý 3537 20 0 3624M 250M 32572 T 0.0 0.4 0: 04.35 python .py [INFO/MainProcess] tạo thư mục tạm thời/tmp/pymp-06sjm3do – TSM

+0

Tôi giả sử bạn đang sử dụng 'if __name__ == '__main __':' mẹo để bảo vệ hồ bơi của bạn? – BlackBear

Trả lời

0

1) Câu hỏi của bạn có chứa mã khác với mã bạn chạy (Mã được đề cập có cú pháp không đúng và không thể chạy được).
2) mô-đun đa xử lý cực kỳ xấu trong việc xử lý lỗi/báo cáo lỗi xảy ra trong công nhân. Sự cố rất có thể xảy ra trong mã mà bạn không hiển thị. Mã bạn hiển thị (nếu cố định) sẽ chỉ hoạt động mãi mãi và ăn CPU, nhưng nó sẽ không gây ra lỗi với quá nhiều tệp hoặc quy trình mở.

Các vấn đề liên quan