2011-12-06 47 views
13

Trong một hệ thống chạy Linux 2.6.35+ chương trình của tôi tạo ra nhiều tiến trình con và giám sát chúng. Nếu một quá trình con chết tôi làm một số làm sạch và đẻ trứng quá trình một lần nữa. Tôi sử dụng signalfd() để nhận tín hiệu SIGCHLD trong quá trình của tôi. signalfd được sử dụng không đồng bộ bằng cách sử dụng libevent.Xử lý nhiều SIGCHLD

Khi sử dụng bộ xử lý tín hiệu cho tín hiệu thời gian thực, trong khi bộ xử lý tín hiệu đang chạy cho một tín hiệu cụ thể, tín hiệu tương tự phải bị chặn để tránh bị xử lý đệ quy. Nếu nhiều tín hiệu đến lúc đó thì hạt nhân chỉ gọi trình xử lý một lần (khi tín hiệu được bỏ chặn).

Có phải hành vi tương tự khi sử dụng signalfd() không? Kể từ khi xử lý dựa trên signalfd không có vấn đề điển hình liên quan đến việc thực hiện không đồng bộ các trình xử lý tín hiệu thông thường, tôi đã nghĩ hạt nhân có thể xếp hàng tất cả các lần xuất hiện khác của SIGCHLD?

bất cứ ai có thể làm rõ hành vi Linux trong trường hợp này ...

Trả lời

17

Trên Linux, nhiều trẻ em chấm dứt trước khi bạn đọc một SIGCHLD với signalfd() sẽ được nén vào một đơn SIGCHLD. Điều này có nghĩa rằng khi bạn đọc các tín hiệu SIGCHLD, bạn phải dọn dẹp sau khi tất cả trẻ em đã chấm dứt:

// Do this after you've read() a SIGCHLD from the signalfd file descriptor: 
while (1) { 
    int status; 
    pid_t pid = waitpid(-1, &status, WNOHANG); 
    if (pid <= 0) { 
     break; 
    } 
    // something happened with child 'pid', do something about it... 
    // Details are in 'status', see waitpid() manpage 
} 

tôi nên lưu ý rằng tôi đã thực sự nhìn thấy nén tín hiệu này khi hai đứa trẻ chế thông thường chấm dứt tại cùng một lúc. Nếu tôi chỉ làm một đơn waitpid(), một trong những đứa trẻ bị chấm dứt không được xử lý; và vòng lặp trên đã sửa nó.

tài liệu tương ứng:

  • http://man7.org/linux/man-pages/man7/signal.7.html"Ngược lại, nếu nhiều trường hợp của một tín hiệu tiêu chuẩn được cung cấp trong khi dấu hiệu cho thấy hiện đang bị chặn, sau đó chỉ một trường hợp đang xếp hàng đợi"
  • http://man7.org/linux/man-pages/man3/sigwait.3p.html"Nếu trước khi cuộc gọi đến sigwait() có nhiều trường hợp đang chờ xử lý của một số tín hiệu đơn, nó được thực hiện xác định cho dù sau khi trở về thành công có bất kỳ tín hiệu đang chờ xử lý còn lại cho số tín hiệu đó. "
+0

Cảm ơn .. vài câu hỏi ..
Cho phép nói có nhiều sự kiện trong hàng đợi epoll chưa được xử lý bởi quy trình của tôi. Trong trường hợp đó là bạn nói rằng hạt nhân sẽ xếp hàng chỉ có một sự kiện đọc cho SIGCHLD trên signalfd ngay cả khi n quá trình chết? Về việc sử dụng waitpid() trong vòng lặp, vấn đề tôi có với phương pháp này là bạn chỉ có được trạng thái thoát của tiến trình con, nhưng mất thông tin khác mà bạn sẽ nhận được từ struct signalfd_siginfo khi bạn đọc từ signalfd (hoặc siginfo_t khi sử dụng sigaction). Tôi đoán không có cách nào để có được điều đó? – Manohar

+0

@Santhosh lưu ý rằng epoll không xếp hàng các sự kiện mô tả tệp theo nghĩa đen của nó; thay vào đó, nó chỉ báo cáo trạng thái của các bộ mô tả tập tin (khả năng đọc, khả năng ghi). Vì vậy, khi sự kiện xảy ra trên một bộ mô tả tập tin mà làm cho nó dễ đọc, nó không quan trọng có bao nhiêu có - epoll sẽ chỉ báo cáo khả năng đọc.Và lần sau bạn thực hiện epoll_wait(), nó sẽ thực hiện chính xác như cũ (trừ khi bạn sử dụng epoll kích hoạt cạnh - nhưng nó vẫn không báo cáo số lượng sự kiện). Về cấu trúc signalfd_siginfo, tôi tin rằng bạn nói đúng. Nhưng những gì bạn sẽ cần từ đó trong trường hợp của SIGCHLD anyway? –

+2

@Santhosh: cũng lưu ý rằng signalfd() tự nén các tín hiệu SIGCHLD chứ không phải epoll. Điều này có nghĩa không chỉ bạn sẽ không nhận được nhiều sự kiện từ epoll, nhưng bạn sẽ chỉ nhận được một tín hiệu SIGCHLD đơn từ read(); struct signalfd_siginfo của những người khác sẽ bị mất mãi mãi. –

0

Thực tế, cách phức tạp sẽ là waitfd có chức năng cho phép bạn thêm pid cụ thể vào cuộc thăm dò ý kiến ​​()/epoll(). Thật không may, nó đã không được chấp nhận cho Linux năm trước khi nó được đề xuất.

+2

thêm nó như một bình luận không phải là một câu trả lời, xin lỗi. –

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