socket

默认socket调用read, sendto 等函数都是阻塞的

服务端使用select,同时客户端断开tcp连接,read不会阻塞,会返回0;

从上面可以看出select的不足:
1. 检测一个就绪套接字,你需要给所有的套接字FD_ISSET(),若套接字少还行,一旦多了,那就是直接拖速度啊

2. 能够监听的套接字数目有限制,一千多个的套接字对于大一点的网络服务器就是‘呵呵‘了其实还有缺点并不能直接看出来,不过还是要列出来
3. 每次调用select,系统要把套接字集合复制到内核空间
--------------------- 
作者:Mr.shi 
来源:CSDN 
原文:https://blog.csdn.net/u014627661/article/details/50915987 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 

 

使用ET和LT的区别

LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。

ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。

 

下面举一个列子来说明LT和ET的区别(都是非阻塞模式,阻塞就不说了,效率太低):

采用LT模式下,如果accept调用有返回就可以马上建立当前这个连接了,再epoll_wait等待下次通知,和select一样。

但是对于ET而言,如果accpet调用有返回,除了建立当前这个连接外,不能马上就epoll_wait还需要继续循环accpet,直到返回-1,且errno==EAGAIN,

从本质上讲:与LT相比,ET模型是通过减少系统调用来达到提高并行效率的。

 

 

ET模式下的读写

    经过前面几节分析,我们可以知道,当epoll工作在ET模式下时,对于读操作,如果read一次没有读尽buffer中的数据,那么下次将得不到读就绪的通知,造成buffer中已有的数据无机会读出,除非有新的数据再次到达。对于写操作,主要是因为ET模式下fd通常为非阻塞造成的一个问题——如何保证将用户要求写的数据写完。

要解决上述两个ET模式下的读写问题,我们必须实现:

a. 对于读,只要buffer中还有数据就一直读;

b. 对于写,只要buffer还有空间且用户请求写的数据还未写完,就一直写。

 

 

 

同时处理多个流

1. 要么多进程(fork),要么多线程(pthread_create),很不幸这两种方法效率都不高。

2.  于是再来考虑非阻塞忙轮询的I/O方式,我们发现我们可以同时处理多个流了(把一个流从阻塞模式切换到非阻塞模式再此不予讨论):

while true {

for i in stream[]; {

if i has data

read until unavailable

}}

3.复杂度 o(n)

while true {

select(streams[])

for i in streams[] {

if i has data

read until unavailable

}}

4. 复杂度o(1)

while true {

active_stream[] = epoll_wait(epollfd)

for i in active_stream[] {

read or write till

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值