Хорошо, один вопрос за раз.
Для чего они?
Вот простой скелет сервера сокетов:
s_sock = socket.socket()
s_sock.bind()
s_sock.listen()
while True:
c_sock, c_addr = s_sock.accept()
process_client_sock(c_sock, c_addr)
Сервер зациклится и примет соединение от клиента, затем вызовет его функцию процесса для связи с клиентским сокетом. Здесь есть проблема: process_client_sock
может занять много времени или даже содержать цикл (что часто имеет место) .
def process_client_sock(c_sock, c_addr):
while True:
receive_or_send_data(c_sock)
В этом случае сервер больше не может принимать подключения.
Простым решением будет использование многопроцессорности или многопоточности, просто создайте новый поток для обработки запроса, в то время как основной цикл продолжает прослушивать новые соединения.
s_sock = socket.socket()
s_sock.bind()
s_sock.listen()
while True:
c_sock, c_addr = s_sock.accept()
thread = Thread(target=process_client_sock, args=(c_sock, c_addr))
thread.start()
Это работает, конечно, но недостаточно хорошо, учитывая производительность. Поскольку новый процесс / поток требует дополнительной загрузки ЦП и памяти, серверы, не работающие в режиме ожидания, могут получить тысячи соединений.
Итак, системные вызовы select
и poll
пытаются решить эту проблему. Вы даете select
набор файловых дескрипторов и говорите ему, чтобы он уведомлял вас, готов ли какой-либо fd к чтению / записи / или происходит исключение.
блокирует ли он (выбирает) при просмотре ресурса?
Да или нет, зависит от параметра, который вы передали ему.
Как выбрать справочную страницу говорит, он получит struct timeval
параметр
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
Есть три случая:
timeout.tv_sec == 0 и timeout.tv_usec = 0
Без блокировки, немедленно вернуться
тайм-аут == NULL
блокировать навсегда, пока дескриптор файла не будет готов.
время ожидания нормальное
ждать определенное время, если дескриптор файла по-прежнему недоступен, время ожидания и возврат.
Какова цель опроса?
Проще говоря: опрос освобождает процессор для других работ при ожидании ввода-вывода .
Это основано на простых фактах, которые
- Процессор намного быстрее, чем IO
- ожидание ввода-вывода - пустая трата времени, поскольку в большинстве случаев процессор будет простаивать
Надеюсь, это поможет.