服务器端编程常常须要构造高性能的IO模型,常见的IO模型有四种:html
(1)同步阻塞IO(Blocking IO):即传统的IO模型。编程
(2)同步非阻塞IO(Non-blocking IO):默认建立的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。设计模式
(3)IO多路复用(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。服务器
(4)异步IO(Asynchronous IO):即经典的Proactor设计模式,也称为异步非阻塞IO。markdown
同步和异步的概念描述的是用户线程与内核的交互方式:多线程
同步是指用户线程发起IO请求后须要等待或者轮询内核IO操做完成后才能继续执行;mvc
异步是指用户线程发起IO请求后仍继续执行,当内核IO操做完成后会通知用户线程,或者调用用户线程注册的回调函数。异步
阻塞和非阻塞的概念描述的是用户线程调用内核IO操做的方式:socket
阻塞是指IO操做须要完全完成后才返回到用户空间;async
非阻塞是指IO操做被调用后当即返回给用户一个状态值,无需等到IO操做完全完成。
同步阻塞I/O模型是最简单的I/O模型,用户进程在进行I/O操做时被阻塞,以下图所示:
在ASP.NET Core中没有使用多线程或加入异步关键字的模型均为同步阻塞I/O
public IActionResult Sync() { var start = DateTime.Now; Add(); return Json("start:"+start+"||| end:" + DateTime.Now); } void Add() { Thread.Sleep(2000); Console.WriteLine(DateTime.Now); }
在同步非阻塞整个IO请求的过程当中,虽然用户线程每次发起IO请求后能够当即返回,可是为了等到数据,仍须要不断地轮询、重复请求,消耗了大量的CPU的资源。通常不多直接使用这种模型,而是在其余IO模型中使用非阻塞IO这一特性
在ASP.NET Core 中可使用多线程来实现同步非阻塞,在以下代码清单中能够看到,使用多线程调用一个会自动休眠2秒的方法,主线程Sync
会先返回值,而不会阻塞。
public IActionResult Sync() { var thread = new Thread(new ThreadStart(this.Add)); thread.Start(); return Json(DateTime.Now); } void Add() { Thread.Sleep(2000); Console.WriteLine(DateTime.Now); }
而子线程因为被阻塞了2秒,所以时间为:
若是想在同步非阻塞的状况下得到返回的数据,就须要轮询,重复的对线程请求。代码清单中使用while循环轮询线程。
public IActionResult Sync() { short num = 10; var thread = new Thread(new ParameterizedThreadStart(this.Add)); thread.Start(num); while (thread.IsAlive) ; return Json(DateTime.Now + "result:" + result); } void Add(object num) { Thread.Sleep(2000); this.result =(short)num ; Console.WriteLine(DateTime.Now); }
真正的异步IO须要操做系统更强的支持。在异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程指定的缓冲区内,内核在IO完成后通知用户线程直接使用便可。
public IActionResult Async() { var start = DateTime.Now; short num = 10; var result = Add(num).Result; return Json("start:"+ start +" end: " + DateTime.Now + " ||| result: " + result); } async Task<short> Add(short num) { await Task.Delay(2000); return ++num; }
关于异步的更详细的使用可参看 http://www.cnblogs.com/vipyoumay/p/5663950.html
1.同步与异步关注的是消息通讯机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个 调用
时,在没有获得结果以前,该调用
就不返回。可是一旦调用返回,就获得返回值了。换句话说,就是由调用者
主动等待这个调用
的结果。而异步则是相反,调用
在发出以后,这个调用就直接返回了,因此没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会马上获得结果。而是在调用
发出后,被调用者
经过状态、通知来通知调用者,或经过回调函数处理这个调用。
你打电话问书店老板有没有《分布式系统》这本书,若是是同步通讯机制,书店老板会说,你稍等,”我查一下",而后开始查啊查,等查好了(多是5秒,也多是一天)告诉你结果(返回结果)。而异步通讯机制,书店老板直接告诉你我查一下啊,查好了打电话给你,而后直接挂电话了(不返回结果)。而后查好了,他会主动打电话给你。在这里老板经过“回电”这种方式来回调。
2. 阻塞与非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回以前,当前线程会被挂起。调用线程只有在获得结果以后才会返回。非阻塞调用指在不能马上获得结果以前,该调用不会阻塞当前线程。
你打电话问书店老板有没有《分布式系统》这本书,你若是是阻塞式调用,你会一直把本身“挂起”,直到获得这本书有没有的结果,若是是非阻塞式调用,你无论老板有没有告诉你,你本身先一边去玩了, 固然你也要偶尔过几分钟check一下老板有没有返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板经过什么方式回答你结果无关
【1】http://www.jianshu.com/p/77332a3b07b5
【2】http://kb.cnblogs.com/page/85931
【3】https://www.zhihu.com/question/19732473