2016-05-23 18 views
5

Tôi có quy trình cha mẹ, phải tạo ra vài quy trình con. Cách tốt nhất tôi tìm thấy là sử dụng fork + execl. Nhưng sau đó quá trình cha mẹ cần phải biết nếu execl của đứa trẻ cụ thể không thành công hay không, và tôi không biết làm thế nào để thực hiện điều đó.Cách tốt nhất để tạo quy trình con trong linux và xử lý lỗi có thể

 int pid = fork(); 
     if (pid < 0) { 
      std::cout << "ERROR on fork." << std::endl; 
     } if (pid == 0) { 
      execl("/my/program/full/path", (char *)NULL); 
      exit(1); 
     } 
     else { 
      if (/*child's process execl fails*/) { 
       std::cout << "it failed" << std::endl 
      } else { 
       std::cout << "child born" << std::endl 
      } 
     } 

Tôi nghĩ rằng ý tưởng này là không tốt:

int status(0); 
sleep(100); 
int res = waitpid(pid, &status, WNOHANG); 
if (res < 0 && errno == 10) { 
    std::cout << "it failed" << std::endl 
} else { 
    std::cout << "child born" << std::endl 
} 

vì nó không tốt để hy vọng rằng quá trình con sẽ chết sau 100 mili giây, tôi muốn biết rằng chắc chắn là duy nhất mà sẽ xảy ra.

Tôi cũng nghĩ rằng việc tạo kết nối shared_memory hoặc đường ống đặc biệt để kiểm tra như vậy là Cannon chống lại Ong.

Phải có giải pháp đơn giản cho điều đó mà tôi chưa tìm thấy.

Cách tốt nhất để đạt được điều đó là gì?

+0

Chỉ cần sử dụng 'popen' và kiểm tra giá trị trả lại. – Andrew

+0

Giả sử nó vẫn còn sống, làm thế nào tôi có thể chắc chắn rằng execl đã không thất bại? Có thể nó thất bại, và quá trình còn sống chỉ vì nó chưa hoàn thành 'lệnh thoát (1)'. – Arkady

+0

Bạn có muốn kiểm tra xem quy trình của bạn đã được khởi chạy thành công * hay đã hoàn thành * và * trả về trạng thái không *? Cả hai đều khá khác nhau. – Andrew

Trả lời

1

Là giải pháp chung, bạn có thể đăng ký trình xử lý tín hiệu (SIGUSR1) trong phụ huynh bằng cách sử dụng sigaction().

Ở trẻ em: xử lý tín hiệu không đăng ký, nếu execl() gọi không thành công, bạn cần gửi SIGUSR1 cho phụ huynh.

Trong phụ huynh: Mỗi pid con, chúng tôi sẽ lưu trữ trong std :: set. Khi tất cả các child được tạo ra, bạn chỉ cần tạo một thread riêng biệt để theo dõi các child. Trong chức năng thread chỉ cần gọi wait() và loại bỏ pid khỏi tập hợp. Một cách khác để nghe tín hiệu SIGCHLD (nhưng nó sẽ dẫn đến giải pháp phức tạp hơn, vì vậy nếu sinh ra một luồng khác là một tùy chọn tôi muốn sử dụng luồng).

Khi bộ trống thì chúng tôi đã làm.

+0

Trông giống như giải pháp chung tốt. Tôi nghĩ về nó mà không có tín hiệu đặc biệt, nhưng với tín hiệu nó thậm chí trông hoàn toàn hợp lý. Cảm ơn bạn. – Arkady

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