Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Отличия level-triggered и edge-triggered в epoll


Автор: GwinnBleidd 3.11.2009, 02:33
В настоящее время пишу софтину, которая получает готовые к вводу-выводу дескрипторы с помощью epoll.

Почитал маны, там чтото не совсем понятное (для меня) написано на счет режимов level-triggered и edge-triggered. 

Я понял написанное следующим образом (могу ошибаться):

В случае с edge-triggered (НЕ дефолтный режим, когда указан EPOLLET):
1. нам присылают некоторый объем данных
2. мы делаем epoll_wait(), он нам сообщает дескриптор с готовыми данными
3. мы извлекаем часть данных (не все)
4. снова делаем epoll_wait(), который блокируется на неопределенное время изза наличия данных в буфере.
Такое поведение обусловлено тем, что данный режим лишь сообщает об изменении заполненности внутренних буферов, а при неполном извлечении данных такого изменения не происходит.
Соотвественно, чтоб избежать этой ситуации, нужно извлекать все из буферов

А теперь - то, что не понял из манов:
- как себя поведет вызов epoll_wait() в 4м пункте в режиме level-triggered? будет ли блокирован?
- какие явные/неявные преимущества и недостатки несет каждый из режимов?

ЗЫ: гуглил. Выгуглил только эти-же маны, и эти-же маны в ужасном машинном переводе

Автор: MAKCim 3.11.2009, 21:53
Цитата(GwinnBleidd @  3.11.2009,  02:33 Найти цитируемый пост)
- как себя поведет вызов epoll_wait() в 4м пункте в режиме level-triggered? будет ли блокирован?

нет
событие снова добавляется в ready-очередь 
точнее так, все зависит от реализации poll() для конкретного объекта, реализующего файловую семантику
для TCP сокета EPOLLIN будет возвращаться до тех пор, пока есть данные в приемном буфере


Цитата(GwinnBleidd @  3.11.2009,  02:33 Найти цитируемый пост)
- какие явные/неявные преимущества и недостатки несет каждый из режимов?

при использовании LT мы не заблокируемся "по ошибке", но и в таких случаях лучше исключить эту вероятность ;)

во всех остальных случаях ET эффективнее засчет меньшей нагрузке на проц из-за постоянных переходов user <-> kernel

Автор: GwinnBleidd 11.11.2009, 23:16
Цитата(MAKCim @  3.11.2009,  19:53 Найти цитируемый пост)
для TCP сокета EPOLLIN будет возвращаться до тех пор, пока есть данные в приемном буфере

Т.е. если мы извлекли интересующие нас данные и больше не ждем входящей информации (притянуто за уши, но предположим), то вызов epoll_wait() в принципе не будет блокироваться и возникнет поглощающий цикл - т.е. оставлять данные во внутренних буферах сокета вредно ))) Спасибо за разъяснение )

Еще вопрос. 
Где то в интернетах (еще до того, как создал эту тему) встретил инфу, что в режиме edge-triggered epoll_wait()  следует вызывать только после того как recv() вернул EAGAIN, иначе epoll_wait() больше не будет возвращать этот дескриптор, при чем не будет возвращать совсем, независимо от поступления очередных данных на этот сокет. 
На практике же я обнаружил, что на каждое поступление порции данных происходит 1 возврат из epoll_wait(), независимо от того, все ли данные перед этим мы забрали с помощью recv() или нет.
Т.е. фактически, если после recv(), не вернувшего EAGAIN вызвать epoll_wait() мы не получим вновь дескриптор до нового поступления данных или до закрытия соединения. Правильны ли эти выводы?

И еще вопрос, возможно немного мимо темы:
Как получить список сокетов, на которых отсутствует активность в течение определенного времени? (к примеру, чтобы закрыть их)

Автор: MAKCim 12.11.2009, 23:23
Цитата(GwinnBleidd @  11.11.2009,  23:16 Найти цитируемый пост)
Правильны ли эти выводы?

да


Цитата(GwinnBleidd @  11.11.2009,  23:16 Найти цитируемый пост)
Как получить список сокетов, на которых отсутствует активность в течение определенного времени? (к примеру, чтобы закрыть их) 

keepalive probes (man 7 tcp)
устанавливаем TCP_KEEPCNT = 1, TCP_KEEPIDLE = <кол. сек.>, TCP_KEEPINTVL = 1
после этого, если в течении <кол. сек.> на сокете не будет никакой активности, коннет дропается и epoll_wait возвратит ошибку 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)