#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
withO_ASYNC
, а не какой-нибудь древний стиль 1980-хioctl
.5. @сарнольд, я видел, как ты изменился. При использовании
ASYNC
и вызове обратного вызова с уведомлением 1. остановит ли процесс свою текущую процедуру? 2. или и текущая процедура, и процедура обратного вызова выполняются в одно и то же время?