2015-12-29 14 views
5

Tôi có một số quy trình con (sử dụng đa xử lý) và khi chúng dừng lại, mỗi người trong số họ cần thực hiện một số công việc cuối cùng. Một cái gì đó như sau, mà không làm việc mặc dù ...Làm cách nào để đăng ký chức năng "atexit" trong quy trình con đa xử lý của python?

import multiprocessing 
import atexit 

def final(): 
    print "final work" 

def worker(): 
    print 'Doing some work' 
    atexit.register(final) 

if __name__ == '__main__': 
    p = multiprocessing.Process(target=worker) 
    p.start() 
    p.join() 

Vậy làm thế nào tôi có thể làm điều này?

+0

Kiểm tra http://stackoverflow.com/questions/1231599/python-multiprocessing-exit-elegantly-how tương tự như những gì bạn đang cố gắng hoàn thành. –

Trả lời

1

Quá trình bắt đầu qua đa xử lý không thoát bình thường và các chức năng atexit sẽ không bao giờ được gọi. Bạn phải chạy công cụ dọn dẹp bằng tay thông qua một thử/cuối cùng khối, ví dụ:

def worker(): 
    try: 
     print('Doing some work') 
    finally: 
     final() 

Hoặc, nếu bạn thực sự muốn sử dụng atexit (xem dưới đây để biết những hạn chế):

def worker(): 
    try: 
     print('Doing some work') 
    finally: 
     atexit._run_exitfuncs() 

Tại sao các quy trình con không thoát thường?

Về mặt kỹ thuật, vì they quit via os._exit(), bỏ qua bất kỳ công việc dọn dẹp nào (bao gồm các chức năng atexit, __del__() và trình hoàn thiện yếu).

Lý do đằng sau quyết định này là công cụ dọn dẹp rủi ro được thực thi vào thời điểm sai, trong quy trình sai. Hầu hết mã sử dụng atexit (hoặc các cơ chế khác) dự kiến ​​mã sẽ chỉ được thực hiện một lần và chỉ khi trình thông dịch chính thoát (ví dụ, một mã có thể sử dụng atexit để xóa thư mục tạm thời). Bằng cách thực hiện các hàm atexit mỗi khi một tiến trình con thoát, bạn phá vỡ kỳ vọng này và những điều xấu có thể xảy ra. Vì vậy, mặc dù bạn có thể chạy các chức năng atexit qua atexit._run_exitfuncs(), tránh làm như vậy, vì chức năng này không có giấy tờ và bởi vì bạn có thể không phải là người dùng duy nhất của atexit (các thư viện bên thứ ba khác có thể sử dụng nó và bạn có thể giới thiệu lỗi trong mã của họ).

+0

Đây là một quyết định vô lý. chức năng atexit không mong đợi được gọi từ "chính". Họ hy vọng sẽ được gọi trong quá trình mà họ đã được đăng ký. do đó, nó chỉ cần lưu trữ pid đăng ký để biết liệu chúng có thể được gọi hay không. Bất kỳ mô-đun nào sử dụng atexit giờ đây đều bị vô dụng bên trong một công việc đa xử lý ... buộc tôi phải sử dụng Popen thay thế và chọn trạng thái riêng của họ. Tôi thực sự phân chia đa xử lý chỉ để đưa các dọn dẹp thích hợp trở lại. –

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