2010-06-25 10 views
6

tôi đang gặp vấn đề bế tắc với đoạn mã này:deadlocks Python multiprocessing.Queue trên đưa và nhận


def _entropy_split_parallel(data_train, answers_train, weights): 
    CPUS = 1 #multiprocessing.cpu_count() 
    NUMBER_TASKS = len(data_train[0]) 
    processes = [] 

    multi_list = zip(data_train, answers_train, weights) 

    task_queue = multiprocessing.Queue() 
    done_queue = multiprocessing.Queue() 

    for feature_index in xrange(NUMBER_TASKS): 
     task_queue.put(feature_index) 

    for i in xrange(CPUS): 
     process = multiprocessing.Process(target=_worker, 
       args=(multi_list, task_queue, done_queue)) 
     processes.append(process) 
     process.start() 

    min_entropy = None 
    best_feature = None 
    best_split = None 
    for i in xrange(NUMBER_TASKS): 
     entropy, feature, split = done_queue.get() 
     if (entropy < min_entropy or min_entropy == None) and entropy != None: 
      best_feature = feature 
      best_split = split 

    for i in xrange(CPUS): 
     task_queue.put('STOP') 

    for process in processes: 
     process.join() 

    return best_feature, best_split 


def _worker(multi_list, task_queue, done_queue): 
    feature_index = task_queue.get() 
    while feature_index != 'STOP': 
     result = _entropy_split3(multi_list, feature_index) 
     done_queue.put(result) 
     feature_index = task_queue.get() 

Khi tôi chạy chương trình của tôi, nó hoạt động tốt cho một số chạy qua _entropy_split_parallel, nhưng cuối cùng bế tắc. Quy trình gốc đang chặn trên done_queue.get() và quy trình công nhân đang chặn trên done_queue.put(). Vì hàng đợi luôn trống khi điều này xảy ra, việc chặn trên get được mong đợi. Những gì tôi không hiểu là lý do tại sao công nhân đang chặn trên put, vì hàng đợi rõ ràng là không đầy (nó trống!). Tôi đã thử các đối số từ khóa blocktimeout nhưng có cùng kết quả.

Tôi đang sử dụng cổng sau đa xử lý, vì tôi bị kẹt với Python 2.5.


EDIT: Có vẻ như tôi cũng đang gặp sự cố bế tắc với một trong các ví dụ được cung cấp với mô-đun đa xử lý. Đó là ví dụ thứ ba từ dưới cùng here. Sự bế tắc chỉ dường như xảy ra nếu tôi gọi phương pháp thử nghiệm nhiều lần. Ví dụ, thay đổi dưới cùng của kịch bản này:


if __name__ == '__main__': 
    freeze_support() 
    for x in xrange(1000): 
     test() 

EDIT: Tôi biết đây là một câu hỏi cũ, nhưng thử nghiệm cho thấy rằng đây không còn là một vấn đề trên cửa sổ với Python 2.7. Tôi sẽ thử Linux và báo cáo lại.

Trả lời

0

Sự cố này đã biến mất với các phiên bản Python mới hơn, vì vậy, tôi giả sử đó là sự cố với cổng sau. Dù sao, nó không còn là một vấn đề nữa.

4

Tôi nghĩ rằng vấn đề là chuỗi phụ huynh tham gia một chuỗi con mà nó đã vượt qua một Hàng đợi. Điều này được thảo luận về mô-đun đa xử lý là programming guidelines section.

Ở mức nào, tôi gặp phải cùng một triệu chứng mà bạn mô tả, và khi tôi tái cấu trúc logic của mình sao cho luồng chủ không tham gia chủ đề con, không có bế tắc. Logic được tái cấu trúc của tôi liên quan đến việc biết số lượng các mục mà tôi sẽ nhận được từ kết quả hoặc hàng đợi "thực hiện" (có thể dự đoán dựa trên số chủ đề con hoặc số mục trên hàng đợi công việc, v.v.) và lặp vô hạn cho đến khi tất cả chúng được thu thập.

"Toy" minh họa về logic:

num_items_expected = figure_it_out(work_queue, num_threads) 
items_received = [] 
while len(items_received) < num_items_expected: 
    items_received.append(done_queue.get()) 
    time.sleep(5) 

Logic trên tránh sự cần thiết cho các chủ đề cha mẹ tham gia các sợi con, nhưng cho phép các chủ đề mẹ để chặn cho đến khi tất cả các trẻ em được thực hiện. Cách tiếp cận này tránh được vấn đề bế tắc của tôi.

+0

Tôi nghĩ rằng tất cả các hàng đợi phải trống khi các quy trình được nối, vì vậy đây không phải là vấn đề. Thêm vào đó, quy trình tổng thể là bế tắc khi đặt, thay vì tham gia. Tôi chỉ nâng cấp Python (tôi đã bị mắc kẹt với một phiên bản cũ), vì vậy tôi sẽ kiểm tra này ra một lần nữa. – ajduff574

+0

@ajduff trong trường hợp của tôi, bế tắc đã không xảy ra trên tham gia, nhưng đặt là tốt, ngoại trừ việc đặt là trong chủ đề con. Ngoài ra, trong trường hợp của tôi, hàng đợi đã được đưa vào là trống rỗng. Vì vậy, tôi nghĩ rằng nó là giá trị một shot (tức là, tránh thread chủ tham gia các chủ đề con) trong trường hợp của bạn là tốt. – Jeet