2009-11-25 43 views
5

Tôi muốn chạy các quy trình phụ dựa trên giao diện điều khiển tùy ý và quản lý chúng từ một quy trình tổng thể duy nhất. Các giao thức con dựa trên giao diện điều khiển truyền thông qua stdin, stdout và stderr, và nếu bạn chạy chúng trong một giao diện điều khiển chính hãng, chúng sẽ chấm dứt sạch khi bạn nhấn CTRL + C. Một số người trong số họ có thể trong thực tế là một cây các quá trình, chẳng hạn như một kịch bản lô chạy một thực thi mà có thể lần lượt chạy một thực thi để làm một số công việc. Tôi muốn chuyển hướng I/O chuẩn của họ (ví dụ, để tôi có thể hiển thị đầu ra của họ trong cửa sổ GUI) và trong một số trường hợp nhất định gửi cho họ một sự kiện CTRL + C để họ từ bỏ và chấm dứt sạch sẽ.Gửi CTRL + C tới cây con xử lý trên Windows

Hai sơ đồ dưới đây cho thấy cấu trúc bình thường đầu tiên - một quy trình tổng thể có bốn quy trình phụ của người lao động và một số công nhân có quy trình con của riêng họ; và sau đó điều gì sẽ xảy ra khi một trong những công nhân cần phải dừng lại - nó và tất cả các con của nó sẽ nhận được sự kiện CTRL + C, nhưng không có quy trình nào khác sẽ nhận được sự kiện CTRL + C.

Process diagram http://pics.livejournal.com/clockworksaint/pic/0007z5yr/s640x480.png

Ngoài ra, tôi sẽ rất thích rằng không có cửa sổ nào khác hiển thị cho người dùng.

Đây là những gì tôi đã cố gắng (lưu ý rằng tôi đang làm việc trong Python, nhưng giải pháp cho C vẫn sẽ là hữu ích):

  • đẻ trứng một quá trình trung gian thêm với CREATE_NEW_CONSOLE, và sau đó có nó spawn quy trình công nhân. Sau đó, hãy gọi số GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0) khi chúng tôi muốn giết người lao động. Thật không may, CREATE_NEW_CONSOLE dường như ngăn tôi chuyển hướng các kênh I/O tiêu chuẩn, vì vậy tôi không có cách nào dễ dàng để đưa đầu ra trở lại chương trình chính.
  • Tạo ra một quy trình trung gian bổ sung với CREATE_NEW_PROCESS_GROUP và sau đó để nó sinh ra quy trình công nhân. Sau đó, hãy gọi số GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0) khi chúng tôi muốn giết người lao động. Bằng cách nào đó, điều này quản lý để gửi CTRL + C chỉ cho quá trình tổng thể, đó là hoàn toàn vô ích. Khi kiểm tra kỹ hơn, GenerateConsoleCtrlEvent nói rằng CTRL + C không thể được gửi tới các nhóm xử lý.
  • Tạo ra quy trình con với CREATE_NEW_PROCESS_GROUP. Sau đó, gọi GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid) để giết người lao động. Đây không phải là lý tưởng, bởi vì CTRL + BREAK kém thân thiện hơn CTRL + C và có thể sẽ dẫn đến kết thúc lộn xộn hơn. (Ví dụ: nếu đó là một quy trình Python, không thể chặn được KeyboardInterrupt và cuối cùng không có khối nào chạy.)

Có cách nào tốt để làm những gì tôi muốn không? Tôi có thể thấy rằng tôi có thể về mặt lý thuyết xây dựng trên nỗ lực đầu tiên và tìm một số cách khác để giao tiếp giữa các quy trình, nhưng tôi lo rằng nó sẽ trở nên cực kỳ khó xử. Có những ví dụ hay về các chương trình khác đạt được hiệu quả tương tự không? Nó có vẻ đơn giản đến nỗi nó không thể là một yêu cầu không phổ biến.

Trả lời

1

Tôi không biết về quản lý/chuyển hướng stdin et. al., nhưng để quản lý cây con xử lý bạn có cân nhắc sử dụng api Windows Job Objects không?

Có một số câu hỏi khác về quản lý cây quá trình (How do I automatically destroy child processes in Windows?Performing equivalent of “Kill Process Tree” in c++ on windows) và nó trông giống như phương pháp sạch nhất nếu bạn có thể sử dụng nó.

Chương 5 của Windows Via C/C++ by Jeffery Richter có một cuộc thảo luận tốt về cách sử dụng CreateJobObject và các API có liên quan.

+0

Tôi đã xem xét các đối tượng công việc trước đây, nhưng cơ chế duy nhất mà họ cung cấp để dừng công việc là buộc chấm dứt các quy trình của nó. Lý do tôi muốn gửi CTRL + C là cung cấp cho các quy trình một cơ hội để hoàn thành một cách rõ ràng. Lưu ý rằng các nhóm quá trình và CTRL_BREAK_EVENT thực hiện một công việc thỏa đáng nếu tôi không quan tâm cụ thể đến việc gửi CTRL + C. – Weeble

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