- 浏览: 168301 次
文章分类
最新评论
-
西巴拉古呀那:
基于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 486java nio开发 学习博客 http://www.sx ... -
Eclipse Debug不为人知的秘密
2016-04-20 15:40 591转自:http://blog.csdn.net/mgoann ... -
推荐!国外程序员整理的Java资源大全
2016-04-20 12:02 562转自:http://www.importnew.com/14 ... -
Vert.x3异步框架实战
2016-04-20 11:55 1864作者:刘小溪 ... -
给 Android 开发者的 RxJava 详解
2016-04-19 18:00 437转自:http://gank.io/post/560e15be ... -
NIO - FileChannel
2016-04-18 09:24 572转自:http://blog.csdn.net/java20 ... -
NIO - MappedByteBuffer
2016-04-18 09:22 798转自:http://blog.csdn.net/java20 ... -
NIO - Scatter/Gather
2016-04-18 09:23 483转自:http://blog.csdn.net/java20 ... -
两种高性能I/O设计模式(Reactor/Proactor)的比较
2016-04-15 14:18 752转自:http://blog.jobbole.com/596 ... -
IO多路复用机制详解
2016-04-15 11:50 652服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四 ... -
Java RandomAccessFile用法
2016-04-12 22:53 804RandomAccessFile RandomAccess ... -
java编译时生成调试信息选项详解(javac -g)
2016-04-10 19:40 670转自:http://www.iteye.com/topic/ ... -
java -verbose命令
2016-04-10 19:26 491java -verbose[:class|gc|jni] 在 ... -
JVM锁实现探究1:synchronized初探
2016-04-07 11:03 749转自:http://www.majin163.c ... -
JVM锁实现探究2:synchronized深探
2016-04-07 10:39 939转自:http://www.majin163.c ... -
java-String中的 intern()
2016-04-07 10:01 5391. 首先String不属于8种基本数据类型,String是一 ... -
java使用java.lang.management监视和管理 Java 虚拟机
2016-04-06 10:14 902软件包 java.lang.management 提供管理 ... -
JMX 提供的虚拟机检测 API
2016-04-06 10:06 567检测虚拟机当前的状 ... -
内存栅栏和内存对齐
2016-04-05 18:07 933Cache 一致性问题单核 ... -
scala scala.io.Source.fromFile读取文件报错:MalformedInputException: Input length = 1
2016-04-01 10:09 2623val file1 = scala.io.Source.fr ...
相关推荐
进程,内核线程,用户线程,协程,纤程......操作系统世界观.doc
协程、纤维以及增强纤维是计算机编程中的概念,特别是在并发处理和异步编程领域中扮演着重要角色。这里我们将深入探讨这些概念,并结合现代编程语言和技术进行解析。 首先,我们来理解协程(Coroutine)。协程是一...
协程 Coroutine 到底是个啥?
协程协程协程协程协程协程协程协程协程协程协程协程协程协程
每个纤程都有自己的独立栈空间,这使得纤程可以在不同的状态之间进行切换而不会影响到其他纤程。 ##### 1. **上下文切换** Quasar 通过优化上下文切换的过程来提高效率。当一个纤程暂停时,Quasar 会保存该纤程的...
19丨如何用协程来优化多线程业务?.html
如果协程A发生了panic,协程B是否会因为协程A的panic而挂掉? 如果协程A发生了panic,协程B是否能用recover捕获到协程A的panic? 答案分别是:会、不能。 那么下面我们来一一验证,并给出在具体的业务场景下的最佳...
在编程领域,协程是一种控制程序执行流程的机制,它允许程序员在单线程环境中实现类似于多线程的并发操作,但比线程更轻量级。本项目"cpp-修改win32api实现协程"是针对C++语言,利用Windows API中的Fiber特性来构建...
这个示例中,`ReadFileAsync`函数使用了协程来异步读取文件,避免了阻塞主线程。`AsyncReadFile`函数利用`TTask.Run`创建一个新的线程来执行文件读取操作,并在完成后通过回调`OnComplete`将结果传递回主线程。 ...
此外,文档还涉及了协程实践中的一些关键概念,比如“Generator双向通信”,即Generator可以和协程互相通信,使得通过yield控制的代码块可以恢复执行。 在协程的开发实践中,开发者需要关注的点包括开发效率、内存...
Python 协程是一种轻量级的并发机制,它允许单线程内的多个任务协作执行,而无需线程切换带来的开销。协程的核心在于 `yield` 关键字,它使得函数能够暂停执行并保存状态,之后可以从暂停的地方继续。协程在语法上与...
Kotlin协程是一种轻量级的并发机制,它允许开发者编写非阻塞式的代码来处理异步操作,从而提高程序的执行效率。协程的工作原理是通过挂起和恢复函数来控制执行流程,而不是像线程那样进行上下文切换。在Kotlin 1.4.0...
Unity3D是一款强大的跨平台游戏开发引擎,而协程(Coroutine)是Unity中一个非常重要的概念,它允许开发者在执行过程中暂停和恢复一个函数,而不是一次性执行完毕。这对于实现复杂的逻辑,如动画过渡、延时操作、...
C++中的多协程技术,特别是结合Libgo库的使用,是现代并发编程的重要手段。在C++中,多线程常用于实现并发,但线程间的上下文切换和同步锁带来的性能开销是其主要痛点。而协程,作为轻量级的执行单元,可以在单线程...
在Android开发中,Kotlin的协程是一种强大的工具,它能帮助开发者解决异步编程中的复杂性和回调地狱问题。协程允许我们以同步的方式编写异步代码,提高代码的可读性和可维护性。本项目的目标是根据Kotlin的协程设计...
通过在ViewModel中启动协程,并在LiveData的`observe`方法内部使用`liveData` builder,可以确保UI更新在主线程进行。 **7. 悬挂函数和延迟调用** Kotlin的`suspend`函数是协程的核心,它们可以在挂起状态下被暂停...