2016-03-24 20 views
5

Câu trả lời có thể nằm ngay trước mặt tôi trên liên kết bên dưới nhưng tôi vẫn không hiểu. Tôi chắc rằng sau khi ai đó giải thích điều này với tôi, Darwin sẽ gọi điện cho tôi.Tại sao chương trình daemon không xuất hiện mà không tham gia()

Ví dụ là at this link here, mặc dù tôi đã thực hiện một số thay đổi để thử nghiệm và giúp tôi hiểu.

Dưới đây là các mã:

import multiprocessing 
import time 
import sys 

def daemon(): 
    p = multiprocessing.current_process() 
    print 'Starting: ', p.name, p.pid 
    sys.stdout.flush() 
    time.sleep(2) 
    print 'Exiting: ', p.name, p.pid 
    sys.stdout.flush() 

def non_daemon(): 
    p = multiprocessing.current_process() 
    print 'Starting: ', p.name, p.pid 
    sys.stdout.flush() 
    time.sleep(6) 
    print 'Exiting: ', p.name, p.pid 
    sys.stdout.flush() 

if __name__ == '__main__': 
    d = multiprocessing.Process(name='daemon', target=daemon) 
    d.daemon = True 

    n = multiprocessing.Process(name='non-daemon', target=non_daemon) 
    n.daemon = False 

    d.start() 
    time.sleep(1) 
    n.start() 
# d.join() 

Và đầu ra của mã này là:

Starting: daemon 6173 
Starting: non-daemon 6174 
Exiting: non-daemon 6174 

Nếu join() ở cuối là không chú thích, sau đó đầu ra là:

Starting: daemon 6247 
Starting: non-daemon 6248 
Exiting: daemon 6247 
Exiting: non-daemon 6248 

Tôi bối rối b/c giấc ngủ của daemon là 2 giây, trong khi không phải daemon là 6 giây. Tại sao nó không in ra thông báo "Thoát" trong trường hợp đầu tiên? Daemon nên đã thức dậy trước phi daemon và in tin nhắn.

Lời giải thích từ trang web này là như vậy:

Sản lượng không bao gồm “Thoát” Thông điệp từ quá trình daemon , vì tất cả các quá trình phi daemon (bao gồm cả chương trình chính ) thoát ra trước khi quá trình daemon tỉnh dậy từ giấc ngủ 2 giây .

nhưng tôi đã thay đổi nó sao cho daemon phải được đánh thức trước khi không có daemon. Tôi đang thiếu gì ở đây? Cảm ơn trước sự giúp đỡ của bạn.

EDIT: Quên đề cập đến Tôi đang sử dụng python 2.7 nhưng dường như vấn đề này cũng nằm trong python 3.x

Trả lời

4

Đây là một niềm vui một để theo dõi. Các tài liệu có phần gây hiểu nhầm, trong đó chúng mô tả các quy trình không phải daemon như thể tất cả chúng đều tương đương nhau; sự tồn tại của bất kỳ quá trình không daemon nào có nghĩa là quá trình "gia đình" vẫn còn sống. But that's not how it's implemented. Quy trình cha mẹ "bình đẳng hơn" so với các quy trình khác; multiprocessing đăng ký một handler atexit nào sau đây:

for p in active_children(): 
    if p.daemon: 
     info('calling terminate() for daemon %s', p.name) 
     p._popen.terminate() 

for p in active_children(): 
    info('calling join() for process %s', p.name) 
    p.join() 

Vì vậy, khi quá trình chính kết thúc, nó đầu tiênterminate là tất cả daemon tiến trình con, sau đójoin là tất cả các tiến trình con phải chờ trên phi daemon trẻ em và dọn sạch tài nguyên từ số daemon trẻ em.

Bởi vì nó thực hiện dọn dẹp theo thứ tự này, một khoảnh khắc sau khi phi bạn daemonProcessstart s, quá trình chính bắt đầu dọn dẹp và buộc terminate s các daemonProcess.

Lưu ý rằng sửa chữa này có thể đơn giản như join ing các phi daemon quá trình bằng tay, không chỉ join ing các daemon quá trình (mà đánh bại toàn bộ các điểm một daemon hoàn toàn); ngăn không cho người xử lý atexit bị gọi, trì hoãn việc dọn dẹp sẽ terminate số daemon trẻ em.

Có thể cho là một lỗi (có vẻ như đã tồn tại qua 3.5.1; tôi đã tự trách mình), nhưng liệu đó có phải là lỗi hành vi hoặc lỗi tài liệu hay không.

+2

Tôi đã quyết định điều này tạo thành lỗi vì hành vi khác với 'luồng' (mà' đa xử lý 'được giả định là sử dụng quy trình thay vì chuỗi), trong đó chuỗi chủ đề tiếp tục chạy trong khi chuỗi _any_ không phải daemon vẫn còn sống (chính hay nói cách khác). Đã mở [bug # 26633] (https://bugs.python.org/issue26633). – ShadowRanger

+0

thx để đi xa hơn và hơn thế nữa trong việc điều tra vấn đề này. Vui mừng khi nghe tôi không điên và Darwin sẽ không gọi cho tôi, ít nhất là lần này =) – Classified

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