2009-01-27 28 views
5

Tôi đang sử dụng select() trên nền tảng Linux/ARM để xem liệu ổ cắm udp đã nhận được gói hay chưa. Tôi muốn biết bao nhiêu thời gian còn lại trong cuộc gọi chọn nếu nó trả về trước khi thời gian chờ (đã phát hiện một gói).Thời gian còn lại trên một select() gọi

cái gì đó dọc theo dòng:

int wait_fd(int fd, int msec) 
{ 
    struct timeval tv; 
    fd_set rws; 

    tv.tv_sec = msec/1000ul; 
    tv.tv_usec = (msec % 1000ul) * 1000ul; 

    FD_ZERO(& rws); 
    FD_SET(fd, & rws); 

    (void)select(fd + 1, & rws, NULL, NULL, & tv); 

    if (FD_ISSET(fd, &rws)) { /* There is data */ 
     msec = (tv.tv_sec * 1000) + (tv.tv_usec/1000); 
     return(msec?msec:1); 
    } else { /* There is no data */ 
     return(0); 
    } 
} 
+0

Tôi không chắc câu hỏi của bạn là gì. Mã của bạn giải quyết được vấn đề; Thời gian còn lại được ghi vào tham số timeout. Quoth select (2): "Trên Linux, select() sửa đổi thời gian chờ để phản ánh lượng thời gian không ngủ, hầu hết các cài đặt khác không làm điều này. (POSIX.1-2001 cho phép một trong hai hành vi.)" – phihag

+0

@phihag: "giấy phép hoặc là hành vi "... xem chính xác giá trị thời gian chờ sau khi một cuộc gọi chọn là không di động –

Trả lời

3

Điều an toàn nhất là để bỏ qua những định nghĩa mơ hồ của select() và thời gian đó cho mình.

Chỉ cần có thời gian trước và sau khi chọn và trừ đi khoảng thời gian bạn muốn.

+0

Tôi đã kết thúc chỉ làm điều này với một cuộc gọi hàm gettimeofday() trước và sau. – Jamie

1

Nếu tôi nhớ chính xác, sau đó chọn() chức năng đối xử với thời gian chờ và I O tham số/và khi chọn trở lại thời gian còn lại được trả về trong biến thời gian chờ.

Nếu không, bạn sẽ phải ghi lại thời gian hiện tại trước khi gọi và sau đó sẽ nhận được sự khác biệt giữa hai lần.

+0

Tài liệu cho select() nói rằng giá trị timeout 'có thể' được thay đổi nếu các hàm trả về thành công (không hết thời gian chờ). Tôi đã tự hỏi nếu có một thành ngữ đơn giản hoặc gọi thư viện thay thế để làm điều này. – Jamie

+0

Vì bạn đang viết ứng dụng của mình cho một nền tảng cụ thể, tại sao không chỉ thử nó và xem liệu giá trị thời gian chờ có thay đổi sau khi cuộc gọi trên nền tảng đó hay không. –

+0

Tôi vừa đọc lại tài liệu C và tôi đồng ý, việc sử dụng hết thời gian chờ là không rõ ràng. Như Adam nói bạn có thể thử nó và xem cho nền tảng của bạn, nếu không đó là kế hoạch đề xuất của tôi B cho bạn. –

1

Từ "người đàn ông chọn" trên OSX:

Timeout is not changed by select(), and may be reused on subsequent calls, however it 
is good style to re-ini-tialize it before each invocation of select(). 

Bạn sẽ cần phải gọi gettimeofday trước khi gọi chọn, và sau đó gettimeofday xuất cảnh.

[Chỉnh sửa] Dường như Linux là hơi khác nhau:

(ii) The select function may update the timeout parameter to indicate 
      how much time was left. The pselect function does not change 
      this parameter. 

    On Linux, the function select modifies timeout to reflect the amount of 
    time not slept; most other implementations do not do this. This causes 
    problems both when Linux code which reads timeout is ported to other 
    operating systems, and when code is ported to Linux that reuses a 
    struct timeval for multiple selects in a loop without reinitializing 
    it. Consider timeout to be undefined after select returns. 
0

Linux chọn() cập nhật các tham số thời gian chờ để phản ánh thời gian đó đã qua.

Lưu ý rằng đây không phải là di động trên các hệ thống khác (do đó cảnh báo trong hướng dẫn OS X được trích dẫn ở trên) nhưng hoạt động với Linux.

Gilad

-3

Không sử dụng lựa chọn, hãy thử với fd lớn hơn 1024 với mã của bạn và xem những gì bạn sẽ nhận được.

+0

OK ... đây là một chủ đề cũ, nhưng những gì _should_ tôi sử dụng? – Jamie

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