手记

select函数socket编程

套接字编程中的select函数是一个比较重要的概念,是epoll函数的早期版本,是实现I/O复用的关键方法。在对这个方法的了解过程中,走了一些弯路,由于select一直与并发,异步等字眼联系在一起,总觉得select是不阻塞的,事实上它本身是阻塞的。当我苦苦在网上搜索答案却相互矛盾的时候,我知道是时候冷静下来喝一口水,思考自己是否还适合干这一行。不对,是是时候找一本权威的书籍翻阅一下了。

阻塞I/O模型

首先需要了解的是socket阻塞的概念,我们知道socket的读写操作并不是直接向网络中读写,而是向本地的网络缓冲区中读写,每一个socket会被分配一个读和一个写缓冲区,如果当我们希望读取数据,但是缓冲区中还没有数据的时候,那么读方法(recv)会被阻塞知道有足够的数据可以接受,那么这个过程中进程会被阻塞,你的程序不能干别的,只能等。在《UNIX网络编程》一书中,用这样的图来表示这个过程。


image.png

I/O复用模型

第二个需要了解的概念是I/O复用,因为select,包括poll和epoll都是实现这种模型的机制,我不明白为什么要叫I/O复用,但是它的好处是进程阻塞与select函数,而不是阻塞于真正的I/O系统调用,那么这个过程同样书中描述为


image.png


看两张图,好像复用并没有什么优越性,因为它同样要阻塞等待直到在监听的socket列表中有socket读或写操作返回。时间上好像并没有什么差别。

select的优越性

select的优越性主要表现在它可以实现一个线程监听多个socket句柄,而阻塞模型则需要多线程来达到这个目的,所以在并发的大量请求的情况下,这样是能节省很多开销的。还有在设置好timeout后,超过这个时间select将不再阻塞,会返回错误,这样可以接着执行别的操作,一定程度上能达到异步的目的。所以你看,这样就和并发和异步联系上了。



作者:Spring_Bear
链接:https://www.jianshu.com/p/00c2fc70f511


0人推荐
随时随地看视频
慕课网APP