- 浏览: 163073 次
文章分类
最新评论
-
西巴拉古呀那:
基于Spring Boot框架企业级应用系统开发全面实战网盘地 ...
使用 Spring Boot 快速构建 Spring 框架应用 -
小灯笼:
基于Spring Boot框架企业级应用系统开发全面实战网盘地 ...
使用 Spring Boot 快速构建 Spring 框架应用 -
ximeng1234:
spark spark-1.6.1-bin-hadoop2.6 ...
Spark On YARN 环境搭建
转自:
http://blog.csdn.net/blade2001/article/details/10628243
使用协程模型和异步模型的目的都一样,就是在需要等待的时候把CPU让给别的事务,相较于异步,协程的优势在于它将不同事务隔离开,并让程序员可以不用自己管理大量的异步状态,这让程序设计更容易,但这优势只有在异步方式设计中需要涉及到很多不同事务的不同状态时才会显现出来。引入协程、线程、进程,其实是引入多个顺序执行的过程,以协程为例,等待的处理就变成了协程库内部实现的了,在需要等待的地方协程被挂起成waiting状态,协程调度器继续执行别的任务,这时候程序员就不用自己管理状态了,代码一样是按顺序的方式编写。
而服务端需要等待的操作其实并不多,无非是:磁盘IO、数据库、网络,而这些环节又是非逻辑性的代码,只需要初期在机制上设计一次就不需要再动到了,完全可以针对这几个主要环节进行针对性的异步设计,也可以用几个线程把事务隔离开,所以协程的优势其实不明显。
协程的优点:
1. 消耗小, 切换快, 一个进程可以创建成千上万个协程, PK Erlang.
2. 小任务顺序编程很符合人的思维方式, 规避纯异步编程中状态机的复杂性. 使得使用协程写的程序将更加的直观, 逻辑描述方便, 简化编程.纤程用于化异步为同步, 你可以进行一个异步操作以后就切换纤程,等到异步操作完成以后在切换回来,这样,在逻辑上相关的代码就可以写到一个函数里面,而不用人为的分到多个回调函数中。
3. 没有了线程所谓的安全问题, 避免锁机制
协程的缺点:
1. 因为协程的上下文切换依靠的是保存CPU寄存器,自己实现的协程需要格外小心,否则程序很容易出现很难调试的错误
2. setcontext和getcontext函数在i386的CPU架构上是跟LinuxThreads模型不兼容,和linux 2.6以后的NPTL线程模型是兼容的
3. 自己实现的协程不是语言原生支持的,不能像Erlang那样公平调度,也不能像Go语言那样自动扩展栈空间,所以是有一定局限性的。
4. 协程一般只支持所有的协程函数在一个线程里面跑. 无法充分利用多核CPU, 除非把所有的IO和计算操作都剥离成单独的线程.
所以协程适合于状态逻辑比较复杂的事务, 比如一个协议栈的状态机, 或者在线网游里面的任务角色逻辑处理。
实现线程库的一个核心问题是实现线程的切换。线程切换主要做了两件事:一是旧线程执行环境的保存,二是新线程执行环境的恢复。执行环境主要指寄存器和栈空间,栈的切换也是通过寄存器的切换来完成的。
协程是非抢占式用户级线程可以使用两类接口来实现: longjmp和setjmp; swapcontext,makecontext,setcontext.
1 .setjmp用来保存当前的执行环境,longjmp用来还原上次的执行,这样可以实现non-local goto的功能。longjmp和setjmp環境依賴性很高,移植性很低。
2. get/set/makecontext是為操作上下文而提供的POSIX API[5],其中get/makecontext對應著setjmp,而setcontext對應著longjmp。這個API和set/LONGJMP不同,因為能夠指定切換的上下文的入口點和機器堆棧空間,所以可以在新的機器堆棧空間中讓Fiber工作。除此之外,這個API雖然在Windows下沒有被提供,但是POSIX環境下的移植性很高。然而,因為get/setcontext調用了在內部執行系統信號掩碼設定的、被稱為“sigprocmask”的系統調用,和set/longjmp相比,開銷更大。调用getcontext/makecontext,来初始化协程,用swapcontext/setcontext来切换协程。
协程完全运行在用户态,各个协程的切换也只在用户态完成,所以切换开销较小。线程的调度,通常是由操作系统的线程调度器完成,在现代OS中,通常使用抢占式调度策略。而协程的调用,完全依赖于程序员自己,即实现一种合作式调度,只有在主动提出切换时,才会进行切换。
纤程,在其他的语言,比如Python、Lua中都有实现。Python中提供了generate/yield,可以用来简单地模拟协程,而另外一个强大的greenlet库,则是Python中纤程的另一实现。在Lua中,我们可以使用内置的coroutine库。 在Win32中,我们可以使用ConvertThreadToFiber/ConvertFiberToThread,CreateFiber/DeleteFiber来管理协程的创建与销毁, SwitchToFiber来处理Fiber的调度。
现代Unix系统都在ucontext.h中提供用于上下文切换的函数,这些函数有getcontext, setcontext,swapcontext 和makecontext。其中,getcontext用于保存当前上下文,setcontext用于切换上下文,swapcontext会保存当前上下文并切换到另一个上下文,makecontext创建一个新的上下文。实现用户线程的过程是:我们首先调用getcontext获得当前上下文,然后修改ucontext_t指定新的上下文。同样的,我们需要开辟栈空间,但是这次实现的线程库要涉及栈生长的方向。然后我们调用makecontext切换上下文,并指定用户线程中要执行的函数。
在这种实现中还有一个挑战,即一个线程必须可以主动让出CPU给其它线程。swapcontext函数可以完成这个任务
利用setcontext函数实现协程的实验:http://1234n.com/?post/4vzsvm
GUN的Pth项目(http://www.gnu.org/software/pth): 利用这setcontext族函数模拟一个与Pthread兼容的用户代码级别线程库。
C语言中著名的协程项目libtask正是利用setcontext族函数来实现协程,当目标系统不支持setcontext族函数时才用汇编模拟。
libtask的运作方式与Go语言对并行操作的模拟方式更接近,几乎是一模一样的设计,因为libtask和Go语言都是跟Plan 9有颜渊的,据我了解Go和libtask提供的Channel作为协程间通讯的方式都源自Plan 9。
ucontext实现的用户级多线程框架2(抢先式多线程): http://www.cnblogs.com/sniperHW/archive/2012/04/02/2429642.html
How to implement fiber: http://blog.csdn.net/seizef/article/details/6567301
并发编程学习总结(好): http://blog.csdn.net/chgaowei/article/details/7237673
协程实现的基础(好): http://tech.uc.cn/?p=1055
云风写的C 的 coroutine 库(完成度很高): http://blog.codingnow.com/2012/07/c_coroutine.html
http://blog.csdn.net/blade2001/article/details/10628243
使用协程模型和异步模型的目的都一样,就是在需要等待的时候把CPU让给别的事务,相较于异步,协程的优势在于它将不同事务隔离开,并让程序员可以不用自己管理大量的异步状态,这让程序设计更容易,但这优势只有在异步方式设计中需要涉及到很多不同事务的不同状态时才会显现出来。引入协程、线程、进程,其实是引入多个顺序执行的过程,以协程为例,等待的处理就变成了协程库内部实现的了,在需要等待的地方协程被挂起成waiting状态,协程调度器继续执行别的任务,这时候程序员就不用自己管理状态了,代码一样是按顺序的方式编写。
而服务端需要等待的操作其实并不多,无非是:磁盘IO、数据库、网络,而这些环节又是非逻辑性的代码,只需要初期在机制上设计一次就不需要再动到了,完全可以针对这几个主要环节进行针对性的异步设计,也可以用几个线程把事务隔离开,所以协程的优势其实不明显。
协程的优点:
1. 消耗小, 切换快, 一个进程可以创建成千上万个协程, PK Erlang.
2. 小任务顺序编程很符合人的思维方式, 规避纯异步编程中状态机的复杂性. 使得使用协程写的程序将更加的直观, 逻辑描述方便, 简化编程.纤程用于化异步为同步, 你可以进行一个异步操作以后就切换纤程,等到异步操作完成以后在切换回来,这样,在逻辑上相关的代码就可以写到一个函数里面,而不用人为的分到多个回调函数中。
3. 没有了线程所谓的安全问题, 避免锁机制
协程的缺点:
1. 因为协程的上下文切换依靠的是保存CPU寄存器,自己实现的协程需要格外小心,否则程序很容易出现很难调试的错误
2. setcontext和getcontext函数在i386的CPU架构上是跟LinuxThreads模型不兼容,和linux 2.6以后的NPTL线程模型是兼容的
3. 自己实现的协程不是语言原生支持的,不能像Erlang那样公平调度,也不能像Go语言那样自动扩展栈空间,所以是有一定局限性的。
4. 协程一般只支持所有的协程函数在一个线程里面跑. 无法充分利用多核CPU, 除非把所有的IO和计算操作都剥离成单独的线程.
所以协程适合于状态逻辑比较复杂的事务, 比如一个协议栈的状态机, 或者在线网游里面的任务角色逻辑处理。
实现线程库的一个核心问题是实现线程的切换。线程切换主要做了两件事:一是旧线程执行环境的保存,二是新线程执行环境的恢复。执行环境主要指寄存器和栈空间,栈的切换也是通过寄存器的切换来完成的。
协程是非抢占式用户级线程可以使用两类接口来实现: longjmp和setjmp; swapcontext,makecontext,setcontext.
1 .setjmp用来保存当前的执行环境,longjmp用来还原上次的执行,这样可以实现non-local goto的功能。longjmp和setjmp環境依賴性很高,移植性很低。
2. get/set/makecontext是為操作上下文而提供的POSIX API[5],其中get/makecontext對應著setjmp,而setcontext對應著longjmp。這個API和set/LONGJMP不同,因為能夠指定切換的上下文的入口點和機器堆棧空間,所以可以在新的機器堆棧空間中讓Fiber工作。除此之外,這個API雖然在Windows下沒有被提供,但是POSIX環境下的移植性很高。然而,因為get/setcontext調用了在內部執行系統信號掩碼設定的、被稱為“sigprocmask”的系統調用,和set/longjmp相比,開銷更大。调用getcontext/makecontext,来初始化协程,用swapcontext/setcontext来切换协程。
协程完全运行在用户态,各个协程的切换也只在用户态完成,所以切换开销较小。线程的调度,通常是由操作系统的线程调度器完成,在现代OS中,通常使用抢占式调度策略。而协程的调用,完全依赖于程序员自己,即实现一种合作式调度,只有在主动提出切换时,才会进行切换。
纤程,在其他的语言,比如Python、Lua中都有实现。Python中提供了generate/yield,可以用来简单地模拟协程,而另外一个强大的greenlet库,则是Python中纤程的另一实现。在Lua中,我们可以使用内置的coroutine库。 在Win32中,我们可以使用ConvertThreadToFiber/ConvertFiberToThread,CreateFiber/DeleteFiber来管理协程的创建与销毁, SwitchToFiber来处理Fiber的调度。
现代Unix系统都在ucontext.h中提供用于上下文切换的函数,这些函数有getcontext, setcontext,swapcontext 和makecontext。其中,getcontext用于保存当前上下文,setcontext用于切换上下文,swapcontext会保存当前上下文并切换到另一个上下文,makecontext创建一个新的上下文。实现用户线程的过程是:我们首先调用getcontext获得当前上下文,然后修改ucontext_t指定新的上下文。同样的,我们需要开辟栈空间,但是这次实现的线程库要涉及栈生长的方向。然后我们调用makecontext切换上下文,并指定用户线程中要执行的函数。
在这种实现中还有一个挑战,即一个线程必须可以主动让出CPU给其它线程。swapcontext函数可以完成这个任务
利用setcontext函数实现协程的实验:http://1234n.com/?post/4vzsvm
GUN的Pth项目(http://www.gnu.org/software/pth): 利用这setcontext族函数模拟一个与Pthread兼容的用户代码级别线程库。
C语言中著名的协程项目libtask正是利用setcontext族函数来实现协程,当目标系统不支持setcontext族函数时才用汇编模拟。
libtask的运作方式与Go语言对并行操作的模拟方式更接近,几乎是一模一样的设计,因为libtask和Go语言都是跟Plan 9有颜渊的,据我了解Go和libtask提供的Channel作为协程间通讯的方式都源自Plan 9。
ucontext实现的用户级多线程框架2(抢先式多线程): http://www.cnblogs.com/sniperHW/archive/2012/04/02/2429642.html
How to implement fiber: http://blog.csdn.net/seizef/article/details/6567301
并发编程学习总结(好): http://blog.csdn.net/chgaowei/article/details/7237673
协程实现的基础(好): http://tech.uc.cn/?p=1055
云风写的C 的 coroutine 库(完成度很高): http://blog.codingnow.com/2012/07/c_coroutine.html
发表评论
-
java nio开发学习博客
2016-05-01 21:47 451java nio开发 学习博客 http://www.sx ... -
Eclipse Debug不为人知的秘密
2016-04-20 15:40 559转自:http://blog.csdn.net/mgoann ... -
推荐!国外程序员整理的Java资源大全
2016-04-20 12:02 522转自:http://www.importnew.com/14 ... -
Vert.x3异步框架实战
2016-04-20 11:55 1815作者:刘小溪 ... -
给 Android 开发者的 RxJava 详解
2016-04-19 18:00 414转自:http://gank.io/post/560e15be ... -
NIO - FileChannel
2016-04-18 09:24 536转自:http://blog.csdn.net/java20 ... -
NIO - MappedByteBuffer
2016-04-18 09:22 755转自:http://blog.csdn.net/java20 ... -
NIO - Scatter/Gather
2016-04-18 09:23 447转自:http://blog.csdn.net/java20 ... -
两种高性能I/O设计模式(Reactor/Proactor)的比较
2016-04-15 14:18 718转自:http://blog.jobbole.com/596 ... -
IO多路复用机制详解
2016-04-15 11:50 614服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四 ... -
Java RandomAccessFile用法
2016-04-12 22:53 764RandomAccessFile RandomAccess ... -
java编译时生成调试信息选项详解(javac -g)
2016-04-10 19:40 627转自:http://www.iteye.com/topic/ ... -
java -verbose命令
2016-04-10 19:26 459java -verbose[:class|gc|jni] 在 ... -
JVM锁实现探究1:synchronized初探
2016-04-07 11:03 704转自:http://www.majin163.c ... -
JVM锁实现探究2:synchronized深探
2016-04-07 10:39 900转自:http://www.majin163.c ... -
java-String中的 intern()
2016-04-07 10:01 5071. 首先String不属于8种基本数据类型,String是一 ... -
java使用java.lang.management监视和管理 Java 虚拟机
2016-04-06 10:14 874软件包 java.lang.management 提供管理 ... -
JMX 提供的虚拟机检测 API
2016-04-06 10:06 530检测虚拟机当前的状 ... -
内存栅栏和内存对齐
2016-04-05 18:07 897Cache 一致性问题单核 ... -
scala scala.io.Source.fromFile读取文件报错:MalformedInputException: Input length = 1
2016-04-01 10:09 2582val file1 = scala.io.Source.fr ...
相关推荐
进程,内核线程,用户线程,协程,纤程......操作系统世界观.doc
协程;纤维;增强纤维
协程 Coroutine 到底是个啥?
在操作系统中,除了进程和线程外,还有一种较少应用的纤程(fiber,也叫协程)。纤程常常拿来跟线程做对比,对于操作系统而言,它们都是较轻量级的运行态。通常认为纤程比线程更为轻量,开销更小。不同之处在于,纤...
协程协程协程协程协程协程协程协程协程协程协程协程协程协程
如果协程A发生了panic,协程B是否会因为协程A的panic而挂掉? 如果协程A发生了panic,协程B是否能用recover捕获到协程A的panic? 答案分别是:会、不能。 那么下面我们来一一验证,并给出在具体的业务场景下的最佳...
19丨如何用协程来优化多线程业务?.html
orchid是一个构建于强大的boost库基础上的C 库,类似于python下的gevent/eventlet,为用户提供基于协程的并发模型。 协程,顾名思义,协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程...
python协程.pptx
协程,又称微线程,纤程。英文名Coroutine。 首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换...
c++ 下多协程,以及使用libgo,多协程的优势,作用,与多线程对比
使用 C++ 来编写高性能的网络服务器程序,从来都不是件很容易的事情。在没有 应用任何网络框架,从 epoll/kqueue 直接码起的时候尤其如此。即便使用 libevent, libev 这样事件驱动的网络...秘诀就在它这个协程机制里
python协程讲解,
Kotlin协程分析(一)——协程的创建过程和执行过程,资料参考Kotlin v1.4.0 源码及stdlib
协程 kotlin retrofit mvvm的模式
Unity3d协程的自实现,版本2018.2.7f1。博客地址https://blog.csdn.net/here4one
优点1 WarriorMan提供协程调度方法,替代的事件同时也是通过协程调度实现,可以在IO操作方面节省大量时间。2 WarriorMan因为HOOK了PHP TCP Socket类型的流,所以常见的Redis , PDO , Mysqli以及用PHP的系列函数...
异步协程下载器