2013-04-01 38 views
7

Tôi có một vài chức năng gọi lại và tôi muốn khởi chạy như nhiều tiến trình và có tất cả các chấm dứt thông qua tín hiệu từ quá trình cha mẹ.Làm thế nào để chấm dứt đúng quy trình con với đa xử lý trong python

Cách làm hiện tại của tôi là tạo một c_bool dùng chung với multiprocessing.Value và đặt nó thành True, sau đó phân phối nó cho tất cả các quy trình của tôi khi chúng được tạo. quá trình của tôi tất cả chạy một vòng lặp trong khi sử dụng bool chia sẻ như vậy:

while myC_bool: ...keep running... 

tôi có thể sau đó chỉ cần chuyển đổi các bool để False từ quá trình cha mẹ của tôi và tất cả các tiến trình con sẽ hoàn thành vòng lặp và thoát cuối cùng của họ.

Tôi đã được nhiều người biết và đã đọc trong tài liệu mà mọi người nên thử tránh sử dụng bộ nhớ dùng chung khi sử dụng đa xử lý. Tôi đã nói với cách tốt nhất để tránh điều này là để daemonize quá trình, cung cấp cho nó một xử lý tín hiệu tùy chỉnh và gửi nó một sigint/sigterm/etc ...

Câu hỏi của tôi là, là độc quyền sử dụng bool để giữ một vòng lặp sống và CHỈ bao giờ thay đổi giá trị của nó từ quá trình cha mẹ của tôi, và đọc nó từ nhiều tiến trình con một giải pháp thích hợp để làm cho tất cả các quy trình con của tôi chấm dứt nhanh chóng và an toàn? Tôi cảm thấy như có ít chi phí cho tất cả các trẻ em chỉ cần nhìn vào một bool chia sẻ, hơn là gửi x số sigints cho họ.

Daemonizing có phải là giải pháp tốt hơn không? Nếu vậy tôi muốn một số giúp hiểu tại sao.

Trả lời

9

Có rất nhiều lý do chính đáng để đi với giải pháp của bạn:

  • Nó dễ dàng hơn để suy nghĩ về hơn tín hiệu.
  • Có ít vấn đề đa nền tảng để giải quyết.
  • Bạn đã có mã hoạt động theo cách này.
  • Giúp dễ dàng thêm cơ chế "tắt máy duyên dáng" nếu bạn muốn trong tương lai.

... v.v.

Hãy nhớ rằng, trừ khi bạn có thể chứng minh với mình rằng multiprocessing và nguyên bản của hệ điều hành cơ bản, trên mọi nền tảng bạn quan tâm, được đảm bảo hoạt động mà không đồng bộ hóa tại đây, bạn cần đặt Lock hoặc một thứ khác xung quanh mọi quyền truy cập vào bool được chia sẻ. Điều đó không hoàn toàn phức tạp, nhưng… một khi bạn đã thực hiện điều đó, sử dụng, ví dụ: Event mà không có bool chia sẻ có thể đơn giản hơn.

Ở mức nào, nếu có lý do nào trong số đó là lý do của bạn, tôi sẽ nói tuyệt vời, hãy làm theo cách đó. Tuy nhiên, theo câu hỏi của bạn, bạn thực sự chọn này vì hiệu suất:

tôi cảm thấy như có ít overhead cho tất cả các trẻ em chỉ cần nhìn vào một trong những chia sẻ bool, hơn là gửi số x của sigints cho họ

Nếu đó là lý do của bạn, bạn gần như chắc chắn sai. Các trẻ em phải nhìn vào bool chung (và có được khóa chia sẻ!) Mỗi ​​lần thông qua một số vòng lặp, trong khi một tín hiệu chỉ phải được gửi đến từng đứa trẻ một lần. Vì vậy, chi phí của bạn gần như chắc chắn sẽ cao hơn nhiều theo cách này. Nhưng thực sự, tôi không thể tưởng tượng chi phí của việc gửi một tín hiệu cho mỗi quá trình con, hoặc thậm chí lấy một khóa interprocess một lần cho mỗi vòng lặp cho mỗi quá trình, là bất cứ nơi nào gần một nút cổ chai trong bất kỳ chương trình hữu ích, vì vậy ... ngay cả vấn đề ở đây ngay từ đầu? Làm những gì có ý nghĩa nhất theo cách đơn giản nhất.

+0

Cảm ơn bạn đã phản hồi, tôi đánh giá cao sự phê bình về phương pháp tôi đang sử dụng. Tôi đã bỏ qua một thực tế rằng mặc dù họ đang trong các quá trình khác nhau, họ vẫn phải có được một khóa để xem giá trị. Tôi có đúng trong suy nghĩ một lý do để tránh các giá trị được chia sẻ là bởi vì nó làm cho các quy trình giống như luồng hơn, cản trở một số lợi thế của việc sử dụng nhiều quy trình? – LISTERINE

+0

@LISTERINE: Tôi chưa bao giờ nghĩ về nó theo cách đó, nhưng vâng, đó là một cách hay để xem nó. Những bất lợi lớn đối với các chủ đề là các giá trị được chia sẻ (có thể thay đổi) khó hơn lý do hơn là truyền thông điệp, và lập trình đồng thời là đủ cứng mà không cần suy nghĩ về chủng tộc. Nhược điểm cụ thể của CPython là GIL có nghĩa là mã luồng vốn vốn đã được đồng bộ hóa quá mức và kết thúc lên gần như nối tiếp thay vì song song. Giá trị được chia sẻ rõ ràng không tệ như chia sẻ tiềm ẩn và khóa xung quanh một giá trị không tệ bằng GIL, nhưng chúng quay lại những nhược điểm của luồng. – abarnert

+0

@ LISTERINE:… Điều đó đang được nói, điều đáng nói đến là các tính năng này tồn tại vì một lý do: Đôi khi bắt đầu với đa xử lý và thực hiện một bước tiến tới luồng là một câu trả lời tốt hơn nhiều so với (a) bắt đầu với luồng và cố gắng di chuyển ra khỏi nó, hoặc (b) tổ chức lại toàn bộ thuật toán của bạn để nó có thể được mã hóa mà không cần chia sẻ. – abarnert

2

Vì bạn cẩn thận về việc ai sửa đổi biến được chia sẻ, điều đó sẽ ổn.

Có nhiều giải pháp khác nhau có thể. Ví dụ. sử dụng multiprocessing.Event và có quá trình chấm dứt khi được đặt. Hoặc sử dụng multiprocessing.Connection đối tượng (từ Ống). Cái sau có thể được sử dụng cho giao tiếp hai chiều giữa cha mẹ và con cái. Giống như một tín hiệu cho trẻ em dừng lại, theo sau là một xác nhận cho phụ huynh.

0

Những người nói với bạn "đừng làm điều này" là sai. Điểm chung của bộ nhớ là chia sẻ bộ nhớ giữa các bộ xử lý đa và đó chính xác là những gì bạn đang làm.

Bạn có giải pháp 1) đơn giản và 2) hoạt động. Cách tiếp cận tín hiệu/daemon là 1) thực sự tuyệt vời và 2) khó mã hơn và 3) khó hiểu hơn nhiều.

Lỗ hổng duy nhất tôi thấy trong cách tiếp cận của bạn là khả năng một quá trình có thể thấy một bản sao cũ của bool từ bộ nhớ cache của CPU và bị trì hoãn một chút khi tắt. Có nhiều cách để xóa bộ nhớ cache để đảm bảo rằng điều này không xảy ra, nhưng có thể bạn không cần chúng bởi vì đối với hầu hết các ứng dụng, việc xả bộ nhớ cache xảy ra thường đủ tự động.

Đứng vững.

+0

Bạn thực sự không nên chỉ tin tưởng "đối với hầu hết các ứng dụng bộ nhớ cache xả nước xảy ra thường đủ tự động". Nếu bạn không biết chắc chắn rằng điều đó xảy ra thường xuyên (hoặc bao giờ hết) cho ứng dụng của bạn trên mọi nền tảng mà bạn quan tâm, bạn cần đồng bộ hóa một cách rõ ràng. Nếu không, bạn chắc chắn rằng mã của bạn sẽ sụp đổ trên bản demo lớn đầu tiên, hoặc bạn sẽ phải mất hàng tuần để tìm ra các tệp heisenbugs chỉ xảy ra trên một vài máy của người dùng (và dĩ nhiên họ sẽ là người dùng không có đầu mối làm thế nào để gửi báo cáo lỗi hữu ích). – abarnert

+0

Cảm ơn bạn đã trả lời, tôi đã không nhận thức được sự đổ vỡ mà bạn đề cập thậm chí là một biến chứng mà tôi có thể gặp phải. Có vẻ như tôi có nhiều nghiên cứu hơn để làm. – LISTERINE

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