协程(纤程,微线程)这个概念早就有之,各家互联网公司也都有研究,但在国内各大论坛和大会热起来,还是今年的事。

最近参与讨论开放平台建设和架构设计过程中,有同事提到了使用协程代替线程,能够很大幅度的提高性能。这引发了我们团队极大的兴趣和激烈的讨论。

首先,说明一下什么是协程。

协程是用户态的线程。传统上线程的切换是由操作系统控制的,并且,每次切换都涉及到上下文的保存切换和用户态与内核态之间切换的过程。而协程的切换是由用户自己控制的,并且每次切换只涉及到上下文的保存与切换(即栈的出栈和入栈的过程)。由于同时可能存在多个线程操作同一个资源的问题,使用线程在必要的情况下需要使用“等待-加锁-释放”这样一套动作。而对于同一个线程中的协程同时操作同一个资源时,则没有这样的问题,因为同一个线程中的所有协程都是串行执行的。当然这样也导致了一个问题:架构在同一个线程中多个协程之上的程序,是无法利用多核资源的。最后,协程还有一个好处,则是协程能够产生更高可读性的代码。

在提出了协程之后,我也提供其他几个可供比较的概念。进程,线程,回调。 
      进程和线程就不多说了。了解一个进程包含一个或者多个线程,一个线程包含一个或者多个协程。在Linux中,创建进程和线程耗费的资源是一致的。
      这里强调一下回调。回调函数相对于协程而言,不会造成上下文的保存和切换,因此切换速度最快,但是也造成了使用回调函数没有上下文的问题。当需要上下文时,只能使用全局变量来保存,不符合大部分程序员的编程习惯。

然后,描述一下是因为什么问题导致了我们发现需要协程的。 
      在高并发应用中,尤其是Web应用,每台服务器都同时会有n多的连接和逻辑处理,每个连接之间没有逻辑关联。传统上对于每个连接请求,都会创建一个进程或者线程来处理该请求(先进一 点的会使用池化技术),这样如果某种类型的请求的处理线程由于各种问题导致处理耗时过长,则由于时间片全部耗费在此线程上导致问题非常严重,会因为一个请 求的问题导致所有请求都变慢或者不可用。
       我们希望当某个请求出现问题时,不会影响到其他的请求。

纯粹的将请求种类强制划分开来,不同线程处理不同的请求是可以解决这个问题的,但是,终归会有部分CPU耗费在处理时间很长的请求上,另外,更换应用的时候,总会有大量配置甚至代码级别的更新,并非完美的解决方案。
      将同步处理过程转化为异步当然也可以解决此问题。但并非所有的同步处理过程都可以异步处理。

 

协程是如何解决这个问题的。

《Windows核心编程 via C/C++》一书说:fiber(Windows中的协程叫做纤程fiber)只是为了使Unix的程序更加容易移植到Windows上来而提供的,建议Windows开发者不要使用fiber。我觉得这其实是不全对的,需要看场景。作者说不要使用fiber,是因为上下文的保存和切换可以由线程来解决而回调函数可以解决在同一线程中内的切换问题,一样不需要锁,并且速度更快。但在高并发应用中,则不一样,面对回调需要使用编程复杂的状态机和令人绝望的调试,fiber的上下文保存和切换则轻松的替换掉这些,并且编程实现上非常干净和漂亮。这是我们选择使用协程的原因。

当然,问题并非协程就可以解决。首先异步IO与之结合是不可避免的。其次对任何一个Web服务器,后端都有非常多的Service的。一个Request,可能会涉及到多个Service。这就需要使用Furture模式,使任何一个Request只需要等待时间最长的一个Service而不用串行等待所有的Service。再次,比较复杂的是,对于协程的调度,我们需要实现一个调度器,使对协程的调用,总是能调度到请求Service完成的协程上,而没有完成的协程,则不会被调度。

结合这些设计元素,一个使用协程的Web服务器就能高效的运作起来。

协程应用场景

http://blog.csdn.net/huyiyang2010/article/details/6042326

协程在Web服务器中的应用(配的图还不错)的更多相关文章

  1. 简单介绍什么是协程及其在ES6中的实现方式

    协程,英文名coroutine,是一种执行过程可以被暂停和恢复的方法.各个协程之间相互协作完成一个任务. 让我们来看一个关于发挥协程作用的例子.假定我们有一个生产者和消费者的关系,生产者创建物品并将物 ...

  2. 您的请求在Web服务器中没有找到对应的站点”这是什么原因?出现这个界面说明域名解析已经正确并生效,这是由于域名没有绑定好,

    宝塔出现 您的请求在Web服务器中没有找到对应的站点"这是什么原因?出现这个界面说明域名解析已经正确并生效,这是由于域名没有绑定好 , 本人经过测试使用如下方法解决.允话空HTTP_REFE ...

  3. python day 20: 线程池与协程,多进程TCP服务器

    目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...

  4. php在web服务器中的工作原理

    1.web工作原理 我是学习PHP网站建设的,那么网站在客户端和服务端的运行是网站运行的根本所在,那个这个运行过程是怎样的呢?我们一探就将! Web:终端 服务器web:我们把提供(响应)服务的计算机 ...

  5. web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)

    知识点:1.使用多线程,多进程,协程完成web并发服务器 2.单进程-单线程-非堵塞也可以实现并发服务器 1.多进程和协程的代码在下面注释掉的部分,我把三种写在一起了 import socket im ...

  6. 用python实现自己的http服务器——多进程、多线程、协程、单进程非堵塞版、epoll版

    了解http协议 http请求头 GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Pragma: no-cache Cache-Co ...

  7. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

  8. C#中使用Socket实现简单Web服务器

    上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 熟悉Socket编程: 熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重 ...

  9. Unity中的协程(一)

    这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn. ...

随机推荐

  1. windows cmd 查看文件目录树

    windows + R ⇒ 输入 cmd ⇒ 进入 windows 命令行界面: tree/?:命令提示: tree:不输入任何参数,输出一棵目录树 不显示文件,只显示目录: tree/F:递归显示目 ...

  2. 深度理解IIS下部署ASP.NET Core2.1 Web应用拓扑图

    原文:深度理解IIS下部署ASP.NET Core2.1 Web应用拓扑图 IIS部署ASP.NET Core2.1 应用拓扑图 我们看到相比Asp.Net, 出现了3个新的组件:ASP.NET Co ...

  3. 如何编辑SDE数据库(转载)

    转自原文 如何编辑SDE数据库(转载) 如何编辑SDE数据(转自ESRI中国社区) (2008-12-15 17:26:41) 很多刚入门的朋友对SDE数据并不太了解,接二连三的在社区里面发问,有时也 ...

  4. ios开发手势处理之手势识别二

    #import "ViewController.h" @interface ViewController ()<UIGestureRecognizerDelegate> ...

  5. php函数实现显示几秒前,几分钟前,几天前等方法(网络上什么都有)

    php函数实现显示几秒前,几分钟前,几天前等方法(网络上什么都有) 一.总结 网络上面什么函数都有 二.php函数实现显示几秒前,几分钟前,几天前等方法 现在很多网站的时间显示都很人性化,不再是单纯的 ...

  6. Android菜鸟的成长笔记(27)——SurfaceView的使用

    前面有关自定义View中进行了绘图,但View的绘图机制存在如下缺陷: 1.View缺乏双缓冲机制. 2.当程序需要更新View上的图像时,程序必须重绘View上显示的整张图片. 3.新线程无法直接更 ...

  7. QT学习记录之理解信号槽机制

    作者:朱金灿 来源:http://blog.csdn.net/clever101 QT的事件机制采用的信号槽机制.所谓信号槽机制,简而言之就是将信号和信号处理函数绑定在一起,比如一个按钮被单击是一个信 ...

  8. [Vue] Use basic event handling in Vue

    Let's use a range of events and their modifiers to look at the cool ways we can deal with event hand ...

  9. Android使用JNI实现Java与C之间传递数据

    介绍Java如何将数据传递给C和C回调Java的方法. java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java.C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要 ...

  10. hdu3461Marriage Match IV 最短路+最大流

    //给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio& ...