求在线看实习医生格蕾第三季的网站

网页设计教程与开发
提供各种常见网页效果
提供各种各样的设计教程
装扮QQ,让QQ变得更酷
设计参考,提高自升水平
学习服务器和操作系统
提供各种素材和工具
收藏学习资料
您现在的位置:&&>>&&>>&&>>&&>>&&>>&正文
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
在进行网络编程时,常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式
同步/异步主要针对C端:
同步:c端发出一个功能调用时,在没有得到结果之前,c端死等结果
例如:普通B/S模式(同步):提交请求-&等待服务器处理-&处理完毕返回 这个期间客户端浏览器不能干任何事
异步:c端一个异步过程调用发出后,调用者不会立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
例如:ajax请求(异步): 事件触发-&服务器处理(浏览器可做其他的)-&处理完毕,ajax回调函数处理结果
阻塞/非阻塞主要针对S端:
阻塞(等待):阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回,效率低
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX))
//..处理订单
flock($fp,LOCK_UN);
fclose($fp);
非阻塞(立即返回):指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回,效率高,适合高并发
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
//..处理订单
flock($fp,LOCK_UN);
echo "系统繁忙,请稍后再试";
fclose($fp);
同步、异步和阻塞、非阻塞是组合关系,因此有4种方式:
同步阻塞、同步非阻塞、异步阻塞、异步非阻塞
linux有五种I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3)I/O复用(select 和poll) (I/O multiplexing)
4)信号驱动I/O (signal driven I/O (SIGIO))
5)异步I/O (asynchronous I/O (the POSIX aio_functions))
前四种都是同步,只有最后一种才是异步IO
select、poll、epoll 区别总结:
1、单进程最大连接数:
select:单个进程所能打开的最大连接数有FD_SETSIZE宏定义
poll:poll本质上和select没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的
epoll:虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,2G内存的机器可以打开20万左右的连接
2、文件描述符(FD)剧增后带来的IO效率问题
select:每次调用文件描述符(FD)时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的"线性下降性能问题"
poll:同上
epoll:根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。
3、 消息传递方式
select:内核需要将消息传递到用户空间,都需要内核拷贝动作
poll:同上
epoll:epoll通过内核和用户空间共享一块内存来实现的。
综上,在选择select,poll,epoll时要根据具体的使用场合以及这三种方式的自身特点。
1、表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。
2、select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
以上这篇浅谈socket同步和异步、阻塞和非阻塞、I/O模型就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
转载请注明:破洛洛(谢谢合作)
上一篇文章: 下一篇文章:
网友评论:
[][][][][][][][][][]您现在的位置:&&>>&&>>&&>>&&>>&正文
linux网络编程中阻塞和非阻塞socket的区别
  非阻塞的write操作一般写法是:
  int write_pos = 0;
  int nLeft = nL
  while (nLeft & 0)
  int nWrite = 0;
  if ((nWrite = write(sock_fd, data + write_pos, nLeft)) &= 0)
  if (errno == EWOULDBLOCK)
  nWrite = 0;
  }else return -1; //表示写失败
  nLeft -= nW
  write_pos += nW
  return nL
  建立连接阻塞方式下,connect首先发送SYN请求道,当客户端收到返回的SYN的确认时,则
  connect
  返回.否则的话一直阻塞.
  非阻塞方式,connect将启用TCP的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.
  接收连接对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返回。
  非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK,表示本来应该阻塞。
  无阻塞的设置方法
  方法一:fcntl
  if (flag = fcntl(fd, F_GETFL, 0) &0) perror("get flag");
  flag |= O_NONBLOCK;
  if (fcntl(fd, F_SETFL, flag) & 0)
  perror("set flag");
  方法二:ioctl
  int b_on = 1;
  ioctl (fd, FIONBIO, &b_on);&&&[2]&
【责编:peter】
没有相关文章
?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]?&[]
相关产品和培训
 友情推荐链接
 认证培训
 专题推荐
 ? ? ? ? ? ? ? ? ? ?
 今日更新
?&?&?&?&?&?&?&?&?&?&
 社区讨论
 博客论点
 频道精选
 C/C++频道相关导航主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
关注软件开发和互联网业界
浮躁的心不会积淀出成功的土壤,清幽的路上风景更美好!阻塞socket和非阻塞socket
对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返
回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲
区中的数据大于期望读取的字节数时,读取期望读取的字节数,返回实际读取的长度。
对于非阻塞socket而言,socket的接收缓冲区中有没有数据,read调用都会立刻返回。接收缓冲区中有
数据时,与阻塞socket有数据的情况是一样的,如果接收缓冲区中没有数据,则返回错误号为
EWOULDBLOCK,
表示该操作本来应该阻塞的,但是由于本socket为非阻塞的socket,因此立刻返回,遇到这样的情况,可
以在下次接着去尝试读取。如果返回值是其它负值,则表明读取错误。
因此,非阻塞的rea调用一般这样写:
if ((nread = read(sock_fd, buffer, len)) & 0)
&if (errno == EWOULDBLOCK)
&&&return 0; //表示没有读到数据
&&}else return -1; //表示读取失败
}读到数据长度
对于写操作write,原理是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,
表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者
是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。
而对于阻塞Socket而言,如果发送缓冲区没有空间或者空间不足的话,write操作会直接阻塞住,如果有
足够空间,则拷贝所有数据到发送缓冲区,然后返回.
非阻塞的write操作一般写法是:
int write_pos = 0;
int nLeft = nL
while (nLeft & 0)
&int nWrite = 0;
&if ((nWrite = write(sock_fd, data + write_pos, nLeft)) &= 0)
&&if (errno == EWOULDBLOCK)
&&&&&&&&&&&&&&&&&&{
&&&nWrite = 0;
&&&&}else return -1; //表示写失败
&nLeft -= nW
&&&&&&&&write_pos += nW
&&&阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则
返回.否则的话一直阻塞.
&&&非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是
立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.
对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返
非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK,表示本来应
无阻塞的设置方法
方法一:fcntl
if (flag = fcntl(fd, F_GETFL, 0) &0) perror(&get flag&);
flag |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flag) & 0)
perror(&set flag&);
方法二:ioctl
int b_on = 1;
ioctl (fd, FIONBIO, &b_on);
Views(...) Comments()

我要回帖

 

随机推荐