2009-05-19 17 views
12

Chúng tôi có lỗi lâu dài trong mã sản xuất của chúng tôi. Đây thực chất là một daemon dựa trên socket. Nó lắng nghe một loạt các trình biên dịch bằng cách chọn.Chọn EBADF: FD nào xấu?

Thỉnh thoảng (một lần một ngày hoặc lâu hơn), chọn sẽ trở lại với EBADF.

Tôi đã viết mã để tìm kiếm người gửi bản ghi xấu, vòng lặp đó trên từng fd và cuộc gọi chọn trên đó. Những cuộc gọi này không bao giờ trả lại EBADF. Tôi cũng đã thử fstat. Họ cũng không bao giờ trả lại EBADF.

Tôi cũng viết lại daemon để sử dụng cuộc thăm dò ý kiến. Điều này không giúp được gì.

Có ai có một số ý tưởng khác không? (ngoài tôi đã mắc phải một sai lầm ngớ ngẩn, đó là tất cả để dễ dàng để làm với chọn).

Trả lời

4

Tôi đồng ý với James. Với poll(), bạn có revents cho mỗi fd có thể dễ dàng được kiểm tra.

I.e.

struct pollfd fds[NUM_FDS]; 
int ret, i; 

... 

ret = poll(fds, NUM_FDS, POLL_TIMEOUT); 
for (i = 0; i < NUM_FDS; i++) 
    if (fds[i].revents & POLLHUP || fds[i].revents & POLLNVAL) 
    ... do something ... 

Tất nhiên bạn sẽ không thực hiện theo cách đó trong thế giới thực, chỉ là ví dụ. Tôi đã ngừng sử dụng select() một thời gian dài trước đây, poll() là một giao diện tốt hơn nhiều. Bạn đã đúng, quá dễ dàng để tự bắn mình vào chân với select().

4

Rất có thể là select được gọi trên bộ mô tả tệp đã đóng. Nguồn thông thường là sử dụng lại fd_set mà không cần khởi tạo lại nó. Bạn có điều gì đang diễn ra trong bộ xử lý tín hiệu không? (như mở lại một tệp nhật ký trên HUP?)

3

Nếu bạn sử dụng thăm dò ý kiến ​​() thì bạn có thể đi qua dữ liệu và tìm kiếm fd nào không thành công, đó là lợi thế lớn.

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