网络I/O模型

IOCP
        传统的服务器端 / 客户端模式通常为每一个客户端创建一个独立的线程,这种实现方式在客户端数量不多的情况下问题不大,但对于类似于铁路网络订票这样的瞬间客户数量巨大的系统来说,效率极端低下。这是因为一方面创建新线程操作系统开销较大,另一方面同时有许多线程处于运行状态,操作系统内核需要花费大量时间进行上下文切换,并没有在线程执行上花更多的时间。
        因此,微软在 Winsocket2 中引入了 IOCP(Input/Output Completion Port)模型。IOCP 是 Input/Output Completion Port(I/O 完成端口)的简称。简单的说,IOCP 是一种高性能的 I/O 模型,是一种应用程序使用线程池处理异步 I/O 请求的机制。Java7 中对 IOCP 有了很好的封装,程序员可以非常方便的时候经过封装的 channel 类来读写和传输数据。
网络I/O模型
        所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数或方法都是同步调用。
        异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调通知调用者

        Client 发送一条请求消息给 Server,Client 并不等待 Server 的处理结果,而是继续发送第二条甚至更多的请求消息。Server 会将这些请求都存入队列,逐条处理,并将处理完的结果回复给 Client。这样一来,Client 就可以不用等待,效率大大提高。

        阻塞调用是指调用结果返回之前,当前线程会被挂起。函数或方法只有在得到结果之后才会返回。阻塞和同步有点类似,但是同步调用的时候线程还是处于激活状态,而阻塞时线程会被挂起

        非阻塞调用和阻塞的概念相对应,指在不能立刻得到结果之前,该函数或方法不会阻塞当前线程而是立刻返回。

传统的网络应用代码

try { 
	 ServerSocket server = new ServerSocket(9080); 
	 while (true) { 
		 Socket client = server.accept(); 
		 new Thread(new SocketHandle(client)).start(); 
	 } 
 } catch (IOException e) { 
	 e.printStackTrace(); 
 }
        相信只要写过网络应用程序的朋友,应该对这样的结构再熟悉不过了。accept 后线程被挂起,等待一个客户发出请求,而后创建新线程来处理请求。当新线程处理客户请求时,起初的线程循环回去等待另个客户请求。 master线程负责路由请求,worker线程负责具体工作 在这个并发模型中, 对每个客户都创建了一个线程 。其优点在于等待请求的线程只需要做很少的工作,而大部分的时间,该线程在休眠,因为 accept 处于阻塞状态。如前文所述,创建线程的开销远远大于程序员的预计,尤其是在并发量巨大的情况下,这种传统的并发模型效率极端低下。

        解决这个问题的方法之一就是 IOCP,说白了 IOCP 就是一个消息队列。我们设想一下,如果事先开好 N 个线程,让它们 hold 住,将所有用户的请求都投递到一个消息队列中去。让后这 N 个线程逐一从消息队列中去取出消息并加以处理。这样一来,就可以避免对每个用户请求都开新线程,不仅减少了线程的资源,也提高了线程的利用率(多个消费者),跟银行取号存款的过程差不多。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值