2013-09-05 36 views
5

Tôi đang cố gắng để viết các bài kiểm tra với nose được thiết lập với một cái gì đó được tính toán bằng cách xử lý đa.thử nghiệm python đa xử lý mã hồ bơi với mũi

Tôi có cấu trúc này thư mục:

code/ 
    tests/ 
     tests.py 

tests.py trông như thế này:

import multiprocessing as mp 


def f(i): 
    return i ** 2 


pool = mp.Pool() 
out = pool.map(f, range(10)) 


def test_pool(): 
    """Really simple test that relies on the output of pool.map. 
    The actual tests are much more complicated, but this is all 
    that is needed to produce the problem.""" 
    ref_out = map(f, range(10)) 
    assert out == ref_out 

if __name__ == '__main__': 
    test_pool() 

Chạy từ thư mục code, python tests/tests.pyđi.

nosetests tests/tests.pykhông thành công để hoàn tất. Nó bắt đầu lên, nhưng không bao giờ được thông qua các cuộc gọi đến pool.map và chỉ bị treo.

Tại sao điều này và giải pháp đơn giản nhất là gì?

+0

Có thể là 'nose' đang sử dụng một số luồng và/hoặc đăng nhập khi chạy kiểm tra. Điều này * có thể * dẫn đến deadlocks khi trộn với multiprocessing trên hệ thống UNIX. Đây không phải là một vấn đề với việc thực hiện python nhưng với chính hàm 'fork()', chỉ làm cho nhánh hiện tại, xem [this] (http://stackoverflow.com/questions/6078712/is-it-safe-to -fork-from-in-a-thread/6079669 # 6079669) trả lời cho một lời giải thích chi tiết hơn. – Bakuriu

+0

Tôi tin rằng giải pháp duy nhất (?) Sẽ là giả lập mô đun 'đa xử lý '. Trong thực tế, tôi không thấy những gì ví dụ của bạn đang thử nghiệm. Nó thực sự là một unittest cho phương thức 'multiprocessing.Pool.map', chứ không phải cho hàm' f'! – Bakuriu

+0

Đây là ví dụ tối thiểu tái tạo lỗi của tôi. Tôi đang thử nghiệm một tải các công cụ khác sử dụng kết quả của 'pool.map' làm đầu vào. – aaren

Trả lời

4

Sự cố liên quan đến thực tế là pool.map được gọi là "cấp độ toàn cầu". Thông thường bạn muốn tránh điều đó, bởi vì những câu lệnh này sẽ được thực thi ngay cả khi tệp của bạn được nhập đơn giản.

Mũi phải import your module để có thể tìm thấy thử nghiệm của bạn và sau đó thực hiện chúng, do đó tôi tin rằng sự cố xảy ra trong khi cơ chế nhập vào (Tôi không dành thời gian tìm hiểu lý do chính xác cho hành vi này)

Thay vào đó, bạn nên di chuyển mã khởi tạo của mình vào lịch thi đấu; Mũi hỗ trợ đồ đạc với trang trí with_setup. Đây là một khả năng (có thể là sự thay đổi đơn giản trong khi vẫn giữ poolout như globals):

import multiprocessing as mp 
from nose import with_setup 

pool = None 
out = None 

def f(i): 
    return i ** 2 

def setup_func(): 
    global pool 
    global out 
    pool = mp.Pool() 
    out = pool.map(f, range(10)) 

@with_setup(setup_func) 
def test_pool(): 
    """Really simple test that relies on the output of pool.map. 
    The actual tests are much more complicated, but this is all 
    that is needed to produce the problem.""" 
    global out 
    ref_out = map(f, range(10)) 
    assert out == ref_out 

if __name__ == '__main__': 
    test_pool() 

thực hiện:

$ nosetests tests/tests.py 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.011s 

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