В чем разница между асинхронным и неблокирующим в сокете unix?

#c #network-programming #nonblocking #asyncsocket

#c #сетевое программирование #неблокирующий #asyncsocket #неблокируемость

Вопрос:

Я вижу такой код в nginx:

 if(fcntl(ngx_processes[s].channel[0], F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) == -1) {
...
if (ioctl(ngx_processes[s].channel[0], FIOASYNC, amp;on) == -1) {
...
  

Кто-нибудь может сказать мне, в чем разница между fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) и ioctl(s, FIOASYNC, amp;on) , разве async и nonblocking это не одно и то же??

Комментарии:

1. 1 серия ваших вопросов научила меня держаться подальше от nginx. 🙂

Ответ №1:

FIOASYNC переключает O_ASYNC флаг (который обычно устанавливается в open(2) or fcntl(2) ) для файлового дескриптора, который попросит ядро отправить процессу SIGIO or SIGPOLL , когда файловый дескриптор будет готов к вводу-выводу.

O_ASYNC используется не часто:

  • чрезвычайно сложно правильно обрабатывать ввод-вывод в обработчиках сигналов; их лучше оставить как можно меньше
  • поскольку сигналы прерывают поток управления программой, их выполнение «обходится дороже», чем стандартные системные вызовы, такие как select(2) или poll(2)
  • сигналы предоставляют меньше информации, чем другие вызовы: они сообщают только об одном готовом fd против многих fd, которые могли бы быть готовы.

O_NONBLOCK Не предоставляет никакого уведомления пользовательскому процессу о том, что fd готов к read(2) или write(2) — вместо этого он изменяет поведение read(2) and write(2) и подобных вызовов для немедленного возврата, если файловый дескриптор не готов к чтению или записи. O_NONBLOCK обычно используется в сочетании с select(2) or poll(2) или подобными вызовами, чтобы гарантировать, что основной цикл клиента или сервера не заблокируется на одном конкретном узле и, таким образом, не заставит голодать все его одноранговые узлы.

Комментарии:

1. @sarnold, то есть ты хочешь сказать, что и то, и другое — одно и то же?

2. Также FIOASYNC это совершенно нестандартный / устаревший способ сделать эквивалент O_ASYNC с open или fcntl .

3. @cpuer: Нет, асинхронность и неблокируемость — это совершенно разные понятия.

4. @cpuer: Возможно, у него есть веская причина установить флаг, но он должен делать это санкционированным стандартами способом, используя fcntl with O_ASYNC , а не какой-нибудь древний стиль 1980-х ioctl .

5. @сарнольд, я видел, как ты изменился. При использовании ASYNC и вызове обратного вызова с уведомлением 1. остановит ли процесс свою текущую процедуру? 2. или и текущая процедура, и процедура обратного вызова выполняются в одно и то же время?