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

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

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

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

在提出了协程之后,我也提供其他几个可供比较的概念。进程,线程,回调。 
      进程和线程就不多说了。了解一个进程包含一个或者多个线程,一个线程包含一个或者多个协程。在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. spring boot中servlet启动原理

    启动过程及原理 1 spring boot 应用启动运行run方法 StopWatch stopWatch = new StopWatch(); stopWatch.start(); Configur ...

  2. Fragment使用LocalBroadcastManager接收广播消息

    这种方式不用在配置文件加东西 变量声明 LocalBroadcastManager broadcastManager; IntentFilter intentFilter; BroadcastRece ...

  3. (转自aierong原创技术随笔)sqlserver字符串拆分(split)方法汇总

    sqlserver字符串拆分(split)方法汇总   --方法0:动态SQL法declare @s varchar(100),@sql varchar(1000)set @s='1,2,3,4,5, ...

  4. [NPM] Use custom config settings in your npm scripts

    In addition to package.json level variables (such as name and version), you can have custom conf set ...

  5. Color the ball(杭电1556)

    Color the ball Time Limit : 9000/3000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  6. gen_server笔记

    http://www.ask3.cn/a/jingcaibowen/tech/Erlang/2013/0614/42043.html gen_server是erlang的OTP框架中最常用的“行为模式 ...

  7. HDU 5317 RGCDQ(素数个数 多校2015啊)

    题目链接:pid=5317" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=5317 Prob ...

  8. oracle常规任务

    # su - oracle  oracle> sqlplus "/as sysdba"  SQL> exec dbms_scheduler.disable('MONDA ...

  9. Word 2010/2013 菜单栏添加 MathType 菜单

    一般对于 office 的高级版本,比如 word 2010/2013,在手动安装 mathtype 之后,并不会再 word 的菜单栏,创建 mathtype 按钮,此时需要按照如下步骤,手动导入 ...

  10. 如何将字段中带逗号的SQLite数据库数据导入到MySQL

    以前在数据库导入中没有遇到过什么问题,如下这样导入 load data local infile 'D:\data.csv' into table table1 fields terminated b ...