2010-06-11 31 views
8

Tôi đang sử dụng Linux làm nền tảng lập trình của mình. Tôi đang sử dụng poll(2) để biết thiết bị của tôi có đang kích hoạt sự kiện hay không.thăm dò ý kiến ​​(2) không trống hàng đợi sự kiện

Cuộc gọi đầu tiên của poll là ok; nó chặn và chờ sự kiện xảy ra. Nhưng trong cuộc gọi hàm thứ hai poll, nó sẽ trở lại; nhưng nó nắm bắt sự kiện. Dưới đây là mã của tôi.

ret = poll(fds, 1, 2000); //2 secs timeout 

if(fds[0].revents & POLLIN && ret > 0) 
{ 
    printf("event occur\n"); 
} 

Dường như hàng đợi/bộ đệm không trống. Tôi chỉ giả định thôi.

Bạn nghĩ vấn đề là gì?

Cảm ơn.

Trả lời

5

nếu bạn có sự kiện POLLIN, có nghĩa là "Có dữ liệu để đọc" - bạn có gọi một số chức năng read() trên fd của bạn trước khi poll() 'lại nhập không?

+0

Cảm ơn, nhưng tôi không cần phải đọc dữ liệu đó. Điều quan trọng với tôi là có một sự kiện. Bạn có nghĩ rằng tôi cần phải đọc điều đó. Có cách nào tôi có thể chỉ cần xóa bộ đệm? – domlao

+0

Tôi nghĩ bạn phải đọc dữ liệu đó. –

+0

Tôi thấy, cảm ơn, tôi nghĩ rằng cần phải làm điều đó. – domlao

11

Rõ ràng nếu bạn đang thăm dò dữ liệu đến, bạn nên tiêu thụ dữ liệu sẵn có (gọi là read()) hoặc vẫn sẽ ở đó và cuộc thăm dò sẽ quay trở lại ngay lập tức. Đối xứng không hoạt động thực sự cần thiết cho POLLOUT, nhưng bạn thường muốn gọi hàm viết tiếp theo() càng sớm càng tốt. Vì vậy, như một quy luật của POLLIN -> đọc, POLLOUT -> viết.

Bạn cũng nên đặt lại cấu trúc pollfd trước khi gọi lại cuộc thăm dò ý kiến.

fds[0].fd = sck; 
fds[0].events = POLLIN; 
fds[0].revents = 0; 
ret = poll(fds, 1, 2000); //2 secs timeout 

if(fds[0].revents & POLLIN && ret > 0) 
{ 
    printf("event occur\n"); 
} 

Nếu bạn không đặt lại mỗi lần, rác từ cuộc gọi trước có thể thay đổi hành vi thăm dò ý kiến ​​(tốt, không thực sự, đây chỉ là vấn đề về tính di động).

Trong mã sản xuất, bạn cũng phải kiểm tra giá trị trả về vì cuộc thăm dò ý kiến ​​có thể bị gián đoạn vì một lý do khác so với sự kiện dự kiến ​​(như tín hiệu). Sau đó, bạn thường muốn gọi nó một lần nữa thay vì đọc dữ liệu mà không có sẵn (như một lời nhắc nhở giá trị trả về thăm dò là số lượng các sự kiện, 0 thời gian chờ, -1 một số lỗi, có số trong errno).

Lỗi trên tệp mô tả được cung cấp để thăm dò ý kiến ​​cũng có thể xảy ra. Họ sẽ không làm cho cuộc thăm dò trở lại một lỗi nhưng sẽ đặt POLLERR, POLLHUP hoặc POLLNVAL trong lĩnh vực revent của cấu trúc pollfd cho bộ mô tả tập tin đó. Nếu những sự kiện này được đặt, tính năng đọc cuộc gọi sẽ trả về một số mã lỗi mà bạn có thể kiểm tra.

+0

cảm ơn. thực sự tôi luôn đặt lại các giá trị trong cấu trúc của mình và tôi nghĩ giải pháp tốt nhất là đọc dữ liệu có sẵn. – domlao

+0

Cảm ơn, nhưng có vẻ như tôi đang nhận được một lỗi trong cuộc gọi chức năng đọc của tôi, có vẻ như nó trả về một giá trị -1, errno nói rằng đối số là không hợp lệ, nhưng im chắc chắn các tham số là chính xác. – domlao

+0

Tôi đã thêm một vài dòng khi kiểm tra lỗi. Rất có thể nếu cuộc thăm dò đầu tiên của bạn dừng lại khi hết thời gian chờ hoặc lỗi. Tôi thường sử dụng một tuyên bố chuyển đổi sau mỗi cuộc thăm dò để quản lý trường hợp lỗi và thời gian chờ, mặc định là trường hợp bình thường, nơi một số sự kiện đã xảy ra. Dù sao, nếu đọc thất bại, bạn nên có một lỗi. Bộ mô tả tệp của bạn có được không? Có thể mở không thành công, hoặc không phải để đọc, hoặc tập tin đã bị đóng ... tốt, không cần phải đoán, kiểm tra lỗi. – kriss

4

Thực tiễn tốt được coi là để kiểm tra POLLHUP hoặc POLLNVAL trước khi đọc bộ mô tả tệp. Tuy nhiên, tôi tin rằng read() sẽ chỉ thất bại nếu trường hợp đó xảy ra, trừ khi bỏ phiếu mô tả tệp dự kiến ​​sẽ chặn cho các khoảng thời gian kéo dài, chẳng hạn như modem. Trong trường hợp đó, bạn sẽ treo (tùy thuộc vào những gì bạn đã chuyển đến open()).

Bạn đang có lẽ không:

  • Reading sự kiện FD ở tất cả trước khi tới poll(), hoặc,
  • Đọc tất cả các dữ liệu có sẵn.

Nếu bạn đã khởi tạo cấu trúc pollfd mảng trước khi gọi poll(), không được có bất kỳ 'rác' để nói.

Tuy nhiên, nó có thể là một ý tưởng tốt để kiểm tra và chắc chắn có điều gì đó đáng làm phiền read() để làm trước khi gọi nó.

+0

Cảm ơn, tôi đã đọc một số dữ liệu, nhưng có vẻ như giá trị đọc trả lại giá trị bằng 0, có nghĩa là không có dữ liệu nào được đọc. – domlao

+0

@sasayins, là FD giống như một modem? Chính xác bạn đang thăm dò ý kiến ​​gì? –

4

poll cung cấp cho bạn sự kiện nếu có dữ liệu/sự kiện để đọc/lỗi/khi bạn có thể viết.

Nếu bạn nhận được sự kiện cho biết "có dữ liệu để đọc" và bạn không đọc bất cứ điều gì - vẫn sẽ có "dữ liệu để đọc" vào lần sau bạn gọi poll và bạn nhận được một sự kiện khác.

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