Ubuntu Linux, ядро 2.6.32-45, 64b, Perl 5.10.1
Я подключаю к серверу много новых потоковых сокетов IO :: Socket :: UNIX, и в основном они работают нормально. Но иногда в многопоточной среде на более быстром процессоре они возвращают «Ресурс временно недоступен» (EAGAIN / EWOULDBLOCK). Я использую тайм-аут в Connect, поэтому сокеты переводятся в неблокирующий режим во время подключения. Но у меня период тайм-аута не наступает - он не ждет заметного времени, он быстро возвращается.
Я вижу, что внутри IO :: Socket он пытается подключиться, и если он терпит неудачу с EINPROGRESS или EAGAIN / EWOULDBLOCK, он делает выбор, чтобы дождаться установки бита записи. Пока это кажется нормальным. В моем случае выбор быстро выполняется, подразумевая, что бит записи установлен, а затем код пытается повторно подключиться. (Я предполагаю, что это попытка получить какую-либо ошибку из-за проскальзывания ошибки?) В любом случае повторное подключение снова не удается с EAGAIN / EWOULDBLOCK.
В моем коде это легко исправить с помощью цикла повторной попытки. Но я не понимаю, почему, когда сокет становится доступным для записи, он не может быть повторно подключен. Я думал, что select guard всегда достаточно для неблокирующего соединения. Очевидно нет; Итак, мои вопросы:
- Какие условия приводят к сбою подключения при работе select (устанавливается бит записи)?
- Есть ли лучший способ, чем вращение и повторная попытка, дождаться успешного подключения? Отжим тратит циклы. Вместо этого я бы хотел заблокировать что-то вроде выбора / опроса, но мне все равно нужен тайм-аут.
Спасибо,
- Стив