2014-10-25 2 views
2

Я работаю с TcpStream. Базовая структура Я работаю с это:Как точно работает set_timeout() на TcpStream?

loop { 
    if /* new data in the stream */ { /* handle it */ } 
    /* do a lot of other stuff */ 
} 

Так set_timeout() кажется, что мне нужно, но я немного озадачен о том, как это работает. В документации указано:

Эта функция устанавливает тайм-аут для всех операций блокировки (включая чтение и запись) в этом потоке. Указанный тайм-аут - это относительное время, в миллисекундах, в будущее, после которого тайм-ауты будут отключены. Это означает, что тайм-аут должен периодически перезагружаться, чтобы не допустить его истечения.

Таким образом, я ожидал, что каждый раз, когда вы будете проверять, доступны ли новые данные, я должен был бы сбросить таймаут, иначе у меня будет только Err(TimeOut) через некоторое время.

Но, похоже, это не так: на самом деле, если я установил очень низкий тайм-аут (например, 10 мс) раз и навсегда, цикл делает именно то, что я хочу. Он возвращает новые данные, если они есть, и возвращает Err(TimeOut), если их нет.

Я не понимаю документацию? Безопасно ли мне использовать это поведение?

ответ

1

Я бы ожидал, что он будет работать как тайм-аут сокета, как у вас есть свойство для сокетов в большинстве операционных систем и доступно с языков программирования с SO_TIMEOUT или схожими вещами. При таком тайм-ауте сокета таймер запускается всякий раз, когда вы запускаете операцию блокировки в сокете, например, чтение, запись, подключение. Либо операция будет выполнена в течение периода времени, либо таймер будет запущен, и операция завершится неудачно из-за таймаута. Тайм-аут - это свойство сокета, а не операции, поэтому нет необходимости устанавливать его снова перед каждой операцией.

Но в соответствии с документацией Rust реализовала совершенно другую вещь. Если я правильно интерпретирую документацию, они не устанавливают тайм-аут для каждой операции, а вместо этого устанавливают крайний срок для всех операций этого типа в сокете. То есть, когда таймер установлен на 10 секунд, вы можете иметь несколько чтений за это время, но если по-прежнему будет считаться активным через 10 секунд, он будет остановлен.

Когда один используется для работы с тайм-аутами сокетов на других языках, это поведение не является ожидаемым, и похоже, что у разработчиков Rust есть аналогичные возражения против этого (экспериментального) API. В https://github.com/rust-lang/rust/issues/15802 они предлагают переименовать такие функции от set..timeout до set..deadline, чтобы имя отражало поведение.

+0

Таким образом, документация просто неверна, говоря, что ее необходимо периодически перезагружать, чтобы она не заканчивалась? – Levans

+0

Документация раздражает, но похоже, что они не применяли тайм-ауты для одной операции, но сроки для группы операций. См. Отредактированный пост. –

+0

Ну, если все будет переписано, я думаю, я подожду, чтобы посмотреть, что получится. – Levans

Смежные вопросы