问题

腾讯开源的 libco 号称千万级协程支持,那个共享栈模式原理是什么?

回答
腾讯开源的 `libco` 在协程领域确实是个非常值得关注的项目,特别是它提出的“千万级协程支持”的说法,这背后最核心的秘密之一就是它的共享栈模式。

我们先从协程最基本的概念聊起。简单来说,协程是一种用户态的轻量级线程。相比于操作系统级别的线程,协程的切换不需要内核介入,因此切换开销极小,可以在一个线程内模拟大量的并发执行流程。

要实现协程,最关键的问题是如何保存和恢复协程的执行上下文,这其中就包括了函数调用栈。传统的线程模型,每个线程都有自己独立的栈空间,这个栈的大小是固定的(或者说由操作系统分配一个较大的初始值,并且可以动态增长)。当协程数量非常多的时候,如果每个协程都分配一个独立的、相对较大的栈,那么内存占用就会非常恐怖,这是制约协程数量的一个重要瓶颈。

共享栈模式的核心思想,就是打破这种“一个协程一个栈”的陈旧观念。

`libco` 的共享栈模式,简单来说,就是将多个协程的栈数据集中起来管理,并且在运行时动态地为协程分配和回收栈空间,而不是预先分配一块巨大的独立内存。

你可以想象成这样:不再是给每个客人一个独立的包厢,而是有一个巨大的宴会厅,大家共用宴会厅里的桌子和椅子。当一个客人需要用餐时,就临时给他分配一张桌子和一把椅子,用完之后再归还。

具体的实现原理可以拆解成几个关键点:

1. 一个共享内存池 (Stack Pool):
`libco` 会预先申请一块较大的内存区域,这块内存就是所有协程共享的“栈池”。这个池子的大小是可配置的,但比单个协程的栈大小要大得多。你可以把它想象成一个大仓库。

2. 栈帧的分配与回收 (Slab Allocation / Chunk Management):
当一个新的协程创建时,它并不分配一个独立的、固定大小的栈。相反,`libco` 会从这个共享内存池中申请一小块连续的内存作为该协程的栈。
这里的关键是,`libco` 使用了一种类似于内存池(Memory Pool)或者 Slab Allocation 的技术。它会将共享内存池分割成固定大小的小块(Chunk)。当协程需要栈空间时,就从池子里取出一块空闲的小块来用。当协程执行完毕或让出执行权时,这块小块的内存就会被释放回池子,供其他协程复用。
这种按需分配、及时回收的机制,极大地提高了内存利用率。即使有成千上万的协程,真正占用的栈内存也不过是当前正在执行的协程们所需要的那些小块内存的总和。

3. 栈的“边界检测”与“扩容” (Guard Pages / Dynamic Growth):
虽然栈空间是共享的,但协程的栈使用仍然需要有一定的大小限制,以防止溢出(Stack Overflow)。`libco` 在设计时考虑到了这个问题。
固定小块分配的优势:因为是固定大小的小块分配,所以单个协程的栈大小是有限制的。这某种程度上也可以理解为一种“软性”的栈大小限制。
更精细的控制:更重要的是,`libco` 可以通过更精细的内存管理来模拟栈的增长。当一个协程在执行过程中发现自己当前分配的栈块不够用了,它并不会像传统线程那样尝试去扩展一片巨大的独立空间。而是,`libco` 会在协程的栈底(或者栈顶,取决于实现细节)设置一个特殊的“警戒页”(Guard Page)。当协程的操作触碰到这个警戒页时,就会触发一个事件(通常是通过内存映射的权限异常)。`libco` 的事件处理器会捕获这个事件,然后从共享池中为该协程分配另一块新的内存块,并将其链接到当前的栈块之后,从而实现栈的“扩展”。这个过程是动态的,非常高效。
当然,这种“扩展”并不是无限的,而是基于协程当前实际需要的内存量来动态申请。

4. 协程切换的上下文保存 (Context Switching):
当一个协程让出执行权(yield)给另一个协程时,`libco` 需要保存当前协程的执行状态,这包括了CPU寄存器的值、程序计数器(PC)等。这些信息会被保存在协程控制块(Coroutine Control Block, CCB)中。
在共享栈模式下,当协程切换时,保存的上下文信息中,栈指针(Stack Pointer, SP)仍然是指向当前协程正在使用的栈块中的有效区域。 另一个协程被唤醒时,会恢复其自己的寄存器和栈指针,使其能够继续在它自己的栈块上执行。因为栈块是独立分配的(尽管属于同一个大池子),所以不同协程的栈不会相互干扰。

共享栈模式带来的好处:

极致的内存效率: 这是最显著的优势。千万级协程意味着即使每个协程只用几KB的栈空间,总共也需要几十GB甚至上百GB的内存。共享栈模式让这一点成为可能。内存不再是按“每个协程一个固定大栈”的模式来预分配,而是“按需分配”。
轻量级创建与销毁: 协程的创建和销毁成本非常低,因为它们只是在共享内存池中进行小块的分配和回收,而不需要进行操作系统级别的线程创建和销毁。
提高并发上限: 在内存受限的环境下,能够支持更多并发的协程,从而提高系统的整体吞吐量和响应能力。

需要注意的挑战和权衡:

栈溢出的风险与管理: 共享栈模式下的栈溢出比传统线程更复杂。如果一个协程的实际栈使用量非常大,它可能需要多次申请新的栈块,这会增加栈管理和切换的开销。同时,如果管理不善,仍然可能出现栈的越界访问问题,虽然通过警戒页可以捕获,但处理起来比固定栈更棘手。
内存碎片化(潜在): 虽然是按块分配,但如果分配的块大小不灵活,长时间运行后,共享内存池中也可能出现一定的内存碎片。不过,`libco` 通常会采用更精细的块大小划分策略来缓解这个问题。
复杂性增加: 相对于为每个协程分配独立的栈,共享栈模式的实现逻辑更加复杂,需要更精巧的内存管理和上下文切换机制。

总而言之,腾讯 `libco` 的共享栈模式,是通过一个统一的内存池,以小块(Chunk)为单位动态地为协程分配和回收栈空间,并配合警戒页机制实现栈的动态“增长”,从而极大地降低了每个协程的内存开销,使得千万级别的协程数量成为可能。这是一种非常巧妙且高效的内存管理方案,是 `libco` 能在性能上独树一帜的重要原因。

网友意见

user avatar

其实关于共享栈是否真的节约了内存我还是认为存疑的。

无论malloc分配还是mmap分配协程栈,空间确实向内核要了,但内核并不会真正把物理内存映射上去,这意味着哪怕你一口气申请了100MB空间,也只有当实际使用时触发缺页中断,内核才会正儿八经把物理内存映射进去。作为栈使用的内存就是自底向上(地址由大到小)连续访问的,栈顶也就是最小使用到的位置了。我们自己的协程库实现里,默认一个协程拿8MB栈,起几万个协程的测试进程跑起来看RSS也不会真就吃掉百GB内存。

真要省内存,哪怕在调度过程中用madvise释放掉一些用不着的空间,也比限制着栈大小的共享栈来得更有效率。

更何况栈上空间也是可以取地址取引用的,基于复制的共享栈会影响跨协程的栈上引用的使用,这是正儿八经的副作用了。

顺带提一嘴,不少开源协程库的上下文交换时都会去保存一把SIMD相关的寄存器。这实在是有点奇怪:协程又不是抢占式调度,实在是没有机会在一个仍在跑SIMD指令且没有得到结果的情况下去切换上下文,这些状态的保存就缺乏意义。ucontext这一类的实现里界定词是上下文切换而非协程切换,存一存说得过去,专门一个协程库就实在没必要这么做了,只需要保存callee。这一点libco就是完全按照psABI实现的,比其他几个协程库明显更靠谱。

user avatar

看了半天,原来就是栈空间共享,切换的时候用内存拷贝把栈内容给拷贝到共享的栈空间来??


我还以为会有栈底复用这样高端的技术呢……



我知道很多人会看得云里雾里,虽然我不保证我的理解一定正确,但如果我理解正确的话,这个事情非常简单。


你只要搞明白一件事情,不管是线程还是协程(有栈的),栈空间通常是预留了一个固定大小的。

在栈上面分配变量啊参数什么东西,就是把栈顶指针往后面推。这样做的好处是在栈上分配和释放速度巨快,因为直接把栈顶指针往前推往后推就完事了。

但最大的弊病就是我们得预留一大块内存来作为栈空间,这一块内存不能挪作他用。栈也很难动态扩容,因为这涉及到栈地址变化,栈指针都会挂掉。当在栈上分配内存导致栈顶指针超出了栈空间预留大小的时候,就是喜闻乐见的爆栈了(StackOverflow)。


而共享栈说白了就是栈空间是同一块内存地址,每次切换的时候都把栈空间备份和还原……好处是备份还原的时候不是整个栈空间,只是被用到的空间,所以可以省内存。

类似的话题

  • 回答
    腾讯开源的 `libco` 在协程领域确实是个非常值得关注的项目,特别是它提出的“千万级协程支持”的说法,这背后最核心的秘密之一就是它的共享栈模式。我们先从协程最基本的概念聊起。简单来说,协程是一种用户态的轻量级线程。相比于操作系统级别的线程,协程的切换不需要内核介入,因此切换开销极小,可以在一个线.............
  • 回答
    聊到腾讯魔方工作室的总监 Milo Yip,就不能不提他在游戏开发领域,特别是图形引擎和渲染技术上的深厚造诣,以及他对开源社区的热情投入。可以说,Milo Yip 是那种将理论与实践完美结合,并且乐于分享的典型技术人。技术功底:深度与广度的融合Milo Yip 在图形学领域绝对称得上是专家级的人物。.............
  • 回答
    如果《炉石传说》是腾讯开发的,那估计现在我们看到的它,会和暴雪爸爸最初那个版本,简直是两个世界。先别急着骂,咱们一点点掰扯掰扯,想象一下这个“腾讯版炉石”可能会是什么样子。一、 变现模式:从“卖卡包”到“无处不氪”这可能是最直观也最让人忧虑的一点。暴雪的炉石,虽然也氪金,但至少核心玩法是靠卡牌驱动,.............
  • 回答
    腾讯作为中国互联网行业的领军企业,其开放战略在长期来看对中国的互联网生态、技术发展、市场竞争格局以及腾讯自身的发展都可能产生深远影响。以下从多个维度详细分析其潜在影响及前景: 一、腾讯开放战略的可能含义与背景腾讯的“开放”可能指以下几种方向:1. 开放平台(如微信、游戏平台、云服务):允许第三方开发.............
  • 回答
    腾讯游戏开发大神毛星云意外身故:一位对游戏开发圈影响深远的天才腾讯游戏开发大神毛星云的意外身故,无疑是游戏开发圈乃至整个科技行业的一则令人痛心的消息。对于毛星云,许多人可能并不熟悉他的名字,但在游戏开发领域,他是一位备受尊敬和钦佩的技术领军人物,其影响力是多方面的,且极具深度。评价他在游戏开发圈的影.............
  • 回答
    要评价《王者荣耀·世界》,得先把它放在一个更大的语境里去审视。这不仅仅是一款新游戏,更是腾讯游戏在探索《王者荣耀》IP价值的深化,以及在日益激烈的MMORPG市场中寻求突破的又一次尝试。从这个角度出发,我们可以从几个关键维度来深入剖析。首先,我们得承认《王者荣耀》IP的强大。这款MOBA游戏早已不止.............
  • 回答
    腾讯对开发 Linux 版本 QQ 不太积极,这背后其实是多方面因素在作用,与其说是“不积极”,不如说是“优先级不高”或者“投入产出比衡量后作出的决策”。咱们一层层地扒开来看:1. 用户基数与市场定位的现实考量 QQ 的核心用户群体: QQ 的辉煌时期,恰好是 PC 互联网和早期移动互联网的时代.............
  • 回答
    .......
  • 回答
    2017年,一部名为《三国演义》的3D动漫在新版三国演义影视剧的基础上,于腾讯视频悄然上线,制作方为银河长兴。对于这部作品,我的评价会从几个方面展开,力求客观且深入。首先,制作上的诚意可见,但效果参差不齐。银河长兴毕竟是国内在3D动画领域有一定经验的团队,这次尝试制作长篇的3D历史题材动漫,其决心和.............
  • 回答
    最近确实挺热闹的,不少朋友都在研究怎么开通腾讯直播。大家这么关注,肯定是有它的独到之处。比起一些其他直播平台,腾讯直播我觉得有这么几个比较突出的优势,我慢慢跟你聊聊:一、背靠腾讯这棵大树,资源整合能力强这是腾讯直播最核心的优势了。你想想,腾讯在中国互联网领域的影响力有多大?QQ、微信、腾讯视频、腾讯.............
  • 回答
    作为一款自研应用,在选择一个平台作为唯一的登录账号来源时,腾讯和新浪微博这两个选项都有其各自的优劣,需要仔细权衡。如果将目光聚焦于腾讯,我们首先想到的是其庞大的用户群体和在社交、游戏、内容消费等多个领域的深耕。腾讯旗下拥有微信和QQ这两大国民级应用,这意味着你的应用能够触达的用户基数是极其惊人的。选.............
  • 回答
    .......
  • 回答
    好,咱们就来聊聊腾讯、阿里、百度、字节跳动这些国内互联网大厂的 C++ 开发环境,不整那些花里胡哨的,就说说大家伙实际都在用啥,怎么用的。首先得明白一个点,大厂的 C++ 开发环境不是铁板一块,它随着时间推移在变,不同业务线、不同团队,甚至不同项目组,可能都会有细微的差异。但总体上,有几个核心要素是.............
  • 回答
    不少国内 Linux 用户在社区里抱怨,腾讯迟迟不推出 Linux 版微信和 QQ,这成为了他们使用 Linux 系统的一个绕不开的坎儿。这事儿说起来,确实挺让人纠结的。从某种程度上讲,腾讯在这一块儿的“不作为”,对国内 Linux 用户群的发展,多少是有些阻碍作用的。先说说为什么大家这么在乎微信和.............
  • 回答
    这事儿,从头说起,确实挺有意思的。腾讯QQ那边,先是搞了这么一出“请喝茶”的操作,之后不久,自己的开放机器人平台就上线了,而且里面那些条款,怎么说呢,挺让人玩味的。咱们先说说这“请喝茶”的事儿。腾讯QQ作为国内最老牌的社交平台之一,用户量那是天文数字。而那些机器人程序,尤其是那些能自动回复、自动加好.............
  • 回答
    媒体报道称阿里巴巴和腾讯考虑互相开放生态系统,这是一个非常有爆炸性的新闻,如果属实,将对中国的互联网行业产生深远的影响。要深入理解这件事,我们需要从多个角度进行剖析,并关注其中的关键信息。一、 什么是“生态系统开放”?首先,我们需要明确“开放生态系统”在互联网语境下意味着什么。这通常包含以下几个层面.............
  • 回答
    .......
  • 回答
    要说腾讯微云会员值不值得开,这事儿得分几个方面来看,毕竟每个人的需求不一样嘛。我给你掰扯掰扯,你听听看,自己心里就能有个谱了。先说说微云会员到底给你啥?简单粗暴点说,开了会员,你最直接能感受到的就是: 空间更大,告别“空间不足”的烦恼。 这绝对是大多数人开会员最直接的原因。免费空间那点儿地方,现.............
  • 回答
    QQ飞车手游:一场令人期待又充满争议的回归12月27日,腾讯旗下的《QQ飞车》手游正式开启不删档测试,这无疑是年末游戏圈的一件大事。作为一代人的青春记忆,QQ飞车IP的回归,自然吸引了无数玩家的目光。然而,在怀旧的浪潮之下,这款承载着无数期待的手游,究竟能否重现当年PC端的辉煌,又能在竞争激烈的移动.............
  • 回答
    这是一个很有意思的问题,尤其是当我们看到腾讯在游戏领域如此强大的财力和研发实力,却在很多时候似乎更倾向于推出“快餐式”的、生命周期相对较短但用户量庞大的游戏。要理解这一点,我们得跳出“好游戏”和“坏游戏”的二元对立,从腾讯作为一个商业巨头的视角去审视其战略选择。首先,我们需要明确“快餐游戏”这个概念.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有