Goroutine(协程)为何能处理大并发?
简单来说:协程十分轻量,可以在一个进程中执行有数以十万计的协程,依旧保持高性能。
进程、线程、协程的关系和区别:
- 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
- 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。
- 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
堆和栈的区别请参看:http://www.cnblogs.com/ghj1976/p/3623037.html
协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任。
执行协程只需要极少的栈内存(大概是4~5KB),默认情况下,线程栈的大小为1MB。
goroutine就是一段代码,一个函数入口,以及在堆上为其分配的一个堆栈。所以它非常廉价,我们可以很轻松的创建上万个goroutine,但它们并不是被操作系统所调度执行。
和所有其他并发框架里的协程一样,goroutine里所谓“无锁”的优点只在单线程下有效,如果$GOMAXPROCS > 1并且协程间需要通信,Go运行库会负责加锁保护数据,这也是为什么sieve.go这样的例子在多CPU多线程时反而更慢的原因.
http://my.oschina.net/Obahua/blog/144549
goroutine 的一个主要特性就是它们的消耗;创建它们的初始内存成本很低廉(与需要 1 至 8MB 内存的传统 POSIX 线程形成鲜明对比)以及根据需要动态增长和缩减占用的资源。这使得 goroutine 会从 4096 字节的初始栈内存占用开始按需增长或缩减内存占用,而无需担心资源的耗尽。
为了实现这个目标,链接器(5l、6l 和 8l)会在每个函数前插入一个序文,这个序文会在函数被调用之前检查判断当前的资源是否满足调用该函数的需求(备注 1)。如果不满足,则调用 runtime.morestack 来分配新的栈页面(备注 2),从函数的调用者那里拷贝函数的参数,然后将控制权返回给调用者。此时,已经可以安全地调用该函数了。当函数执行完毕,事情并没有就此结束,函数的返回参数又被拷贝至调用者的栈结构中,然后释放无用的栈空间。
通过这个过程,有效地实现了栈内存的无限使用。假设你并不是不断地在两个栈之间往返,通俗地讲叫栈分割,则代价是十分低廉的。
参考资料:
【翻译】为什么 goroutine 的栈内存无穷大?
http://my.oschina.net/Obahua/blog/144549
协程框架的堆栈大小陷阱
http://blog.csdn.net/huyiyang2010/article/details/6104891
Coroutine及其实现
http://www.cnblogs.com/foxmailed/archive/2014/01/08.html
goroutine背后的系统知识
http://www.sizeofvoid.net/goroutine-under-the-hood/
Goroutine(协程)为何能处理大并发?的更多相关文章
- go语言之进阶篇创建goroutine协程
1.goroutine是什么 goroutine是Go并行设计的核心.goroutine说到底其实就是协程,但是它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现 ...
- 进程池和线程池、协程、TCP单线程实现并发
一.进程池和线程池 当被操作对象数目不大时,我们可以手动创建几个进程和线程,十几个几十个还好,但是如果有上百个上千个.手动操作麻烦而且电脑硬件跟不上,可以会崩溃,此时进程池.线程池的功效就能发挥了.我 ...
- 进程池与线程池、协程、协程实现TCP服务端并发、IO模型
进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...
- 协程--gevent模块(单线程高并发)
先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...
- python协程--asyncio模块(基础并发测试)
在高并发的场景下,python提供了一个多线程的模块threading,但似乎这个模块并不近人如意,原因在于cpython本身的全局解析锁(GIL)问题,在一段时间片内实际上的执行是单线程的.同时还存 ...
- Golang教程:goroutine协程
在上一篇中,我们讨论了并发,以及并发和并行的区别.在这篇教程中我们将讨论在Go中如何通过Go协程实现并发. 什么是协程 Go协程(Goroutine)是与其他函数或方法同时运行的函数或方法.可以认为G ...
- Go goroutine (协程)
在Go语言中goroutine是一个协程,但是跟Python里面的协程有很大的不同: 在任何函数前只需要加上go关键字就可以定义为协程; 不需要在定义时区分是否是异步函数 VS async def ...
- Golang 入门 : goroutine(协程)
在操作系统中,执行体是个抽象的概念.与之对应的实体有进程.线程以及协程(coroutine).协程也叫轻量级的线程,与传统的进程和线程相比,协程的最大特点是 "轻"!可以轻松创建上 ...
- go 学习 (五):goroutine 协程
一.goroutine 基础 定义 使用者分配足够多的任务,系统能自动帮助使用者把任务分配到 CPU 上,让这些任务尽量并发运作,此机制在Go中称作 goroutine goroutine 是 Go语 ...
- Golang的goroutine协程和channel通道
一:简介 因为并发程序要考虑很多的细节,以保证对共享变量的正确访问,使得并发编程在很多情况下变得很复杂.但是Go语言在开发并发时,是比较简洁的.它通过channel来传递数据.数据竞争这个问题在gol ...
随机推荐
- Java性能优化之JVM GC(垃圾回收机制)
Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.st ...
- 第七届蓝桥杯个人赛省赛--C语言B组
题目一 煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球? 请 ...
- ldconfig
#ldconfig# http://www.cnblogs.com/lyongde/p/4190588.html ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链 ...
- 《DSP using MATLAB》Problem 4.16
代码: %% ------------------------------------------------------------------------ %% Output Info about ...
- http协议详谈
scheme - 定义因特网服务的类型.最常见的类型是 httphost - 定义域主机(http 的默认主机是 www)domain - 定义因特网域名,比如 runoob.comport - 定义 ...
- 将string str中的str转换成字符数组
#include <iostream> #include <map> #include <string.h> using namespace std; int ma ...
- jsp servlet 进行基于js的用户验证
写这个只是完成使用js文件参数进行用户验证的处理的jsp 版,已经写过 asp.net php nodejs 以及纯js的,现在完善jsp的 使用的技术是比较简单的就是站点应用我们的js脚本,但是是带 ...
- smarty学习——组合修改器
对于同一个变量,你可以使用多个修改器.它们将从左到右按照设定好的顺序被依次组合使用. 使用时必须要用"|"字符作为它们之间的分隔符. 比如: {#userinfoname#} {# ...
- POSIX 线程具体解释(3-相互排斥量:"固定加锁层次"/“试加锁-回退”)
有时一个相互排斥量是不够的: 比方: 当多个线程同一时候訪问一个队列结构时,你须要2个相互排斥量,一个用来保护队列头,一个用来保护队列元素内的数据. 当为多线程建立一个树结构时.你可能须要为每一个节点 ...
- Vquery PHP 简单爬虫类
http://www.thinkphp.cn/topic/36693.html 在使用php进行网页抓取的时候你有没有感觉到用起来比较麻烦呢?目前我还没有发现php有这样针对网页抓取的类,每次用到这个 ...