select函数socket编程
套接字编程中的select函数是一个比较重要的概念,是epoll函数的早期版本,是实现I/O复用的关键方法。在对这个方法的了解过程中,走了一些弯路,由于select一直与并发,异步等字眼联系在一起,总觉得select是不阻塞的,事实上它本身是阻塞的。当我苦苦在网上搜索答案却相互矛盾的时候,我知道是时候冷静下来喝一口水,思考自己是否还适合干这一行。不对,是是时候找一本权威的书籍翻阅一下了。
阻塞I/O模型
首先需要了解的是socket阻塞的概念,我们知道socket的读写操作并不是直接向网络中读写,而是向本地的网络缓冲区中读写,每一个socket会被分配一个读和一个写缓冲区,如果当我们希望读取数据,但是缓冲区中还没有数据的时候,那么读方法(recv)会被阻塞知道有足够的数据可以接受,那么这个过程中进程会被阻塞,你的程序不能干别的,只能等。在《UNIX网络编程》一书中,用这样的图来表示这个过程。
文章图片
image.png I/O复用模型
【select函数socket编程】第二个需要了解的概念是I/O复用,因为select,包括poll和epoll都是实现这种模型的机制,我不明白为什么要叫I/O复用,但是它的好处是进程阻塞与select函数,而不是阻塞于真正的I/O系统调用,那么这个过程同样书中描述为
文章图片
image.png
看两张图,好像复用并没有什么优越性,因为它同样要阻塞等待直到在监听的socket列表中有socket读或写操作返回。时间上好像并没有什么差别。
select的优越性
select的优越性主要表现在它可以实现一个线程监听多个socket句柄,而阻塞模型则需要多线程来达到这个目的,所以在并发的大量请求的情况下,这样是能节省很多开销的。还有在设置好timeout后,超过这个时间select将不再阻塞,会返回错误,这样可以接着执行别的操作,一定程度上能达到异步的目的。所以你看,这样就和并发和异步联系上了。
结尾
还有很多问题比方说select监听多套接字机制,轮询的方法,就不探讨了,有兴趣可以自己看下。
推荐阅读
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- 概率论/统计学|随机变量 的 分布函数 与 概率密度函数 的区别
- spring|spring boot项目启动websocket
- vue组件中为何data必须是一个函数()
- Spring|Spring Boot之ImportSelector
- iOS-Swift-map|iOS-Swift-map filter reduce、函数式编程
- performSelectorOnMainThread:withObject:waitUntilDone:参数设置为NO或YES的区别