我无法理解 python 中的轮询/选择
我正在 python 中使用 UDP 进行一些线程异步网络实验。
我想了解轮询和 select python 模块,我从未在 C/C++ 中使用过它们。
那些是做什么用的?我有点理解一点选择,但是在观看资源时它会阻塞吗?民意调查的目的是什么?
I'm doing some threaded asynchronous networking experiment in python, using UDP.
I'd like to understand polling and the select python module, I've never used them in C/C++.
What are those for ? I kind of understand a little select, but does it block while watching a resource ? What is the purpose of polling ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,一次一个问题。
那些是做什么用的?
这是一个简单的套接字服务器框架:
服务器将循环并接受来自客户端的连接,然后调用其处理函数与客户端套接字进行通信。这里有一个问题:
process_client_sock
可能需要很长时间,甚至包含一个循环(通常是这种情况)。在这种情况下,服务器无法接受更多连接。
一个简单的解决方案是使用多进程或多线程,只需创建一个新线程来处理请求,而主循环继续侦听新连接。
这当然有效,但考虑到性能还不够好。由于新进程/线程需要额外的 CPU 和内存,因此不空闲的服务器可能会获得数千个连接。
所以
select
和poll
系统调用试图解决这个问题。您给select
一组文件描述符,并告诉它在任何 fd 准备好读/写/或发生异常时通知您。它(选择)在观看资源时会阻塞吗?
是或否取决于您传递给它的参数。
正如select man page所说,它将获得
struct timeval
参数分为三种情况:
timeout.tv_sec == 0 和 timeout.tv_usec = 0
无阻塞,立即返回
timeout == NULL
永远阻塞,直到文件描述符准备好。
超时是正常的
等待一定时间,如果仍然没有文件描述符可用,则超时并返回。
民意调查的目的是什么?
简单来说就是:轮询在等待 IO 时释放 CPU 来进行其他工作。
这是基于一个简单的事实:
希望它有帮助。
Okay, one question a time.
What are those for?
Here is a simple socket server skeleton:
Server will loop and accept connection from a client, then call its process function to communicate with client socket. There is a problem here:
process_client_sock
might takes a long time, or even contains a loop(which is often the case).In which case, the server is unable to accept any more connections.
A simple solution would be using multi-process or multi-thread, just create a new thread to deal with request, while the main loop keeps listening on new connections.
This works of course, but not well enough considering performance. Because new process/thread takes extra CPU and memory, not idle for servers might get thousands connections.
So
select
andpoll
system calls tries to solve this problem. You giveselect
a set of file descriptors and tell it to notify you if any fd is ready to read/write/ or exception happens.does it(select) block while watching a resource?
Yes, or no depends on the parameter you passed to it.
As select man page says, it will get
struct timeval
parameterThere are three cases:
timeout.tv_sec == 0 and timeout.tv_usec = 0
No-blocking, return immediately
timeout == NULL
block forever until a file descriptor is ready.
timeout is normal
wait for certain time, if still no file descriptor is available, timeout and return.
What is the purpose of polling ?
Put it into simple words: polling frees CPU for other works when waiting for IO.
This is based on the simple facts that
Hope it helps.
如果您执行
read
或recv
,则您只等待一个连接。如果有多个连接,则必须创建多个进程或线程,浪费系统资源。使用
select
或poll
或epoll
,您可以仅用一个线程监视多个连接,并在其中任何一个有可用数据时收到通知,并且然后您在相应的连接上调用read
或recv
。它可能会无限阻塞、阻塞给定时间或根本不阻塞,具体取决于参数。
If you do
read
orrecv
, you're waiting on only one connection. If you have multiple connections, you will have to create multiple processes or threads, a waste of system resource.With
select
orpoll
orepoll
, you can monitor multiple connections with only one thread, and get notified when any of them has data available, and then you callread
orrecv
on the corresponding connection.It may block infinitely, block for a given time, or not block at all, depending on the arguments.
select() 接受 3 个套接字列表来检查三个条件(读、写、错误),然后返回(通常更短,通常为空)实际准备好处理这些条件的套接字列表。
因此,如果套接字在等待超时秒数后没有尝试连接,则列表 read_to_read 将为空 - 此时accept()和recv()是否会阻塞并不重要 - 它们不会因空而被调用list...
如果一个套接字已准备好读取,那么它将有数据,因此它也不会阻塞。
select() takes in 3 lists of sockets to check for three conditions (read, write, error), then returns (usually shorter, often empty) lists of sockets that actually are ready to be processed for those conditions.
So if a socket has no attempted connections after waiting timeout seconds, then the list ready_to_read will be empty - at which point it doesn't matter if the accept() and recv() would block - they won't get called for the empty list....
If a socket is ready to read, then if will have data, so it won't block then, either.