首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

理解协程的实现

本质上是保存当前的执行上下文到一个变量中,然后去做其他事情。某个时机再切换回来。从上面函数的名字中,我们大概能知道,这些函数的作用。我们先看一下表示上下文的数据结构(x86架构)。...// oEAX是eax字段ucontext_t结构中的位置,这里就是把ucontext_t中eax的值置为0 movl $0, oEAX(%eax) // 同上 movl...执行本上下文的eip时,相当于从一个子函数中返回, 这时候的栈顶应该是esp+4,即跳过eip和恢复ebp的过程。...即下一条要执行的指令的地址。我们从上图可以知道,栈顶这时候指向的元素是上下文的工作函数的地址。所以setcontext返回执行设置的上下文的工作函数。 这时候的栈布局 ?...在这里插入图片描述 当工作函数执行完之后,同样,栈顶的元素出栈,成为下一个eip。即L(exitcode)地址对应的指令会在工作函数执行执行。下面我们分析L(exitcode)。

78540
您找到你想要的搜索结果了吗?
是的
没有找到

协程(coroutine)简介

系统维护线程时需要分配额外的空间,所以线程数的增加还是会提高内存资源的消耗 总结 如果线程之间没有竞争关系、线程占用的内存资源较少且对延时不是非常敏感或者说线程创建频繁(数分钟创建一次),那么直接在使用的时候创建新的线程...注意,如果 setcontext 执行成功,那么调用 setcontext 的函数将不会返回,因为当前 CPU 的上下文已经交给其他函数或者过程了,当前函数完全放弃了 对 CPU 的“所有权” 应用:当信号处理函数需要执行的时候...执行 makecontext 需要为新上下文分配一个栈空间,如果创建,那么新函数func执行时会使用旧上下文的栈,而这个栈可能已经不存在了。argc 必须和 func 中整型参数的个数相等。...RPC 调用的网络耗时一般耗时毫秒级别,RPC 服务的处理耗时也可能在毫秒级别,如果当前服务使用同步调用,即 RPC 返回才进行后续逻辑,那么一条线程每秒处理的业务数量是可以估算的 假设每次业务处理花费...tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port)); // 注意这里的 a.accept() 是阻塞型操作,accept 返回才会创建线程

90320

小白学协程笔记2-c语言实现协程-2021-2-10

所谓协程,无非是程序执行到某一行时保存一下上下文暂时挂起去执行其它任务,恢复时继续从上下文执行。...每次到return i时函数返回,下一次执行时根据switch继续跳转到case LINE:执行,完成了类似的效果。...介绍函数之前,先学习一个ucontext_t类型的结构体,它表示协程的上下文环境: typedef struct ucontext { struct ucontext *uc_link;...执行完 movq 语句,%rsp 指向了第二个参数 coctx_t 中 regs[0],而之后的pop 语句就是用 regs[0-13] 中的值填充cpu 的寄存器,这里需要注意的是popq 会使得...执行完最后一句 popq %rsp ,%rsp 已经指向了新协程要恢复的栈指针(即新协程之前调用 coctx_swap 时父函数的栈帧顶指针),由于每个协程都有一个自己的栈空间,可以认为这一语句使得

1.2K20

也谈谈c语言的协程

一、协程写法 服务器的目的是让程序同时执行多个任务。 服务器并发场景是程序IO密集型有优势。因为IO操作速度远没有CPU的计算速度快。程序阻塞IO将浪费大量CPU时间。...1.1 普通程序(IO同步阻塞) 一种情况accept和recv同一个线程(nginx也是如此,但是nginx的event模型,这个例子当发送io阻塞没有使用event模型设计) ---------...拆散的IO通知需要select/epoll非阻塞多IO模型进行IO完成事件通知。假设还没有select/epoll的年代。...中断点的栈恢复是event handler执行,又可以处理剩下的代码逻辑)。此时主协程从上一个操作出来可以accept别的请求。..., 相当于一串context挨个执行过去,如果为空,则返回 makecontext(&fibre->fibre, async_start_func, 0);//指定这个栈响应的

2.2K380

重玩 40 年前的经典游戏小蜜蜂,这次通关了源码

这里是 HelloGitHub 推出的《讲解开源项目》系列,本期为您讲解的是 80、90 儿时的记忆,诞生于 1978 年的经典街机游戏《太空侵略者》也叫“小蜜蜂”的 C 语言复刻版——si78c。...,指针 prev_ctx 更新为指向 frontend_ctx,指针 curr_ctx 更新为指向 main_ctx,其过程如图所示: 图 3-3 实现解释请见代码 2-2 当 execute() 返回时他会按照正常的执行流程返回到...我们之前提到 main() 中的大循环本质上是模拟街机的硬件行为,真实的机器上中断是只有触发时才会执行,但在 si78c 上我们只能通过 loop_core() 之间调用 irq() 来模拟产生中断并在...if (m.gameTasksRunning == 0) return; // 欢迎界面 且 没有在演示模式,返回(只游戏模式 和 demo模式下继续运行)... si78c 的代码中许多地方都会有这样的提示,这里并不是简单的调用一个不会返回的函数进行套娃。

90320

有栈协程和无栈协程

,当进程内发生函数调用时,需要保存一些上下文信息以及为函数内局部变量分配存储空间,这些存储空间是栈上分配的,具体来说:函数调用之前主调函数会将函数参数和返回地址入栈,被调函数执行之前会先将主调函数的...; 主要包括: uc_links:当前context执行结束执行的下一个context,若为空,表示执行完毕后退出程序;协程库设计中一般用于存主协程的上下文 uc_stack:当前上下文的栈信息...xorl %eax, %eax // 返回函数 ret #endif co_swap主要完成了协程切换的功能,将执行流从curr指向的当前协程切换为pending_co指向的协程,coctx_swap...(对应于leaq 8(%rsp),%rax),因为返回时会从栈顶取返回地址,作为下一条指令的地址,通过这步操作就从上次让出CPU的位置继续执行了 而栈信息通过rbp和rsp指向,而栈顶指针coctx_make...这时另外一种基于上下文恢复的协程机制提供了一种新的思路。

4.6K43

「溯」@ Wasmer: 托管运行环境和可解释的程序状态

以上是 Singlepass 后端所生成的代码执行过程中单个函数的机器状态结构,包含栈帧和寄存器内容的语义信息。...当 Wasmer 的信号处理函数接收到异常信号时,它会尝试获取当前指令地址所对应的机器状态结构,以这一结构为模板读取和解释异常上下文,然后以返回地址为初始指令地址重复这一过程,直到不存在与其对应的机器状态结构...需要解决的主要问题包括: 接收到外部信号时,某个特定的关键位置(循环头部、函数头部)暂停托管代码的执行信号处理函数中,获取异常上下文。 切换到构造好的新机器状态,继续执行用户代码。...第 2 点是利用信号处理函数 undocumented 的第三个 ucontext_t * 参数实现的。这个参数包含了异常的全部上下文信息。...需要注意的是,ucontext_t Linux 和 macOS 上的结构并不一致,这也是跨平台复杂性的来源之一。

87440

云风coroutine库源码分析

ud; // 保存执行前的上下文 ucontext_t ctx; // 所属schedule struct schedule * sch; // 当前栈的最大容量...接下来就是执行协程。 struct coroutine *C = S->co[id] 首先拿到当前需要执行协程的结构体。id是创建协程的时候返回的。接着保存当前执行的上下文。...// 保存当前执行的上下文到ctx getcontext(&C->ctx); getcontext函数之前的文章分析过,他主要是保存当前执行的上下文,即getcontext函数下一条执行的地址和寄存器等信息...从前面的代码中我们知道,协程执行的时候使用的是一个公共的栈,即所有协程共享的。那么如果协程让出执行,其他协程执行时就会覆盖栈里的信息。...那么当前协程让出执行,需要保存这部分上下文,否则他就被覆盖了。做法就是堆上申请一块空间(如果还没有或者大小不够的话)。然后保存公共栈里的上下文。这样其他协程执行的时候就可以覆盖里面的数据了。

71610

小白学协程笔记3-实现自己的协程库(独立栈,共享栈)-2021-2-22

函数指针 */ typedef void (*Func)(void *); /* 协程结构体 */ typedef struct _coroutine_t { /* 协程上下文 */ ucontext_t...刚开始协程库中的协程都处于FREE状态,指定了协程相关函数及参数以后协程变为RUNABLE状态,协程运行时处于RUNING状态,暂停时处于SUSPEND状态,运行完毕处于FREE状态。...coroutine_t &c=schedule.coroutines[id]; c.func=func; c.arg=arg; c.state=RUNABLE; /* 返回协程...: { return 1; } } return 0; } 初次启动时,需要指定协程的栈c.ctxt.uc_stack及协程结束返回时的上下文...不管是初次启动还是暂停恢复,都需要修改协程状态和调度器的runId,最后通过swapcontext切换上下文开始执行协程。

1.1K40

ROP-SROP学习

signal handler 返回,内核为执行 sigreturn 系统调用,为该进程恢复之前保存的上下文,其中包括将所有压入的寄存器,重新 pop 回对应的寄存器,最后恢复进程的执行。...在这四步过程中,第三步是关键,即如何使得用户态的signal handler执行完成之后能够顺利返回内核态。类UNIX的各种不同的系统中,这个过程有些许的区别,但是大致过程是一样的。...这一段就是signal frame 在内核sigreturn系统调用处理函数中,会根据当前的栈指针指向的Signal Frame对进程上下文进行恢复,并返回用户态,从挂起点恢复执行。...sigreturn的地址(或相关gadget) 最后sigreturn的系统调用执行,就直接可以执行自定义的系统调用了 ?...ucontext_t 结构体 X86 struct sigcontext { unsigned short gs, __gsh; unsigned short fs, __fsh; unsigned

1.2K10

Lua 性能剖析

1494214220043.jpg] 我们自己也很容易粗略的构建这样的性能对比例子,比如笔者曾经做过的: [1494214286712_6129_1494214286833.png] 分别调用1000万次,lua的执行时间...问题来了,Lua为什么这么慢,会不会有些使用不当的坑,踩了以后,连慢30倍都是奢望?怎么使用lua,才能尽可能避开性能缺陷,发挥灵活的长处?...C代码加O2优化执行时间不足1ms, gcc编译器已经可以看出测试代码中的调用是没有意义的,自动优化掉了。 Lua编译器远达不到这么好的优化程度。...collectable object)都被标记为白色,垃圾回收启动,会从全局表和Lua栈出发,把所有可以到达的GCObject全部标记为黑色,标记完成,把所有保持白色的GCObject释放掉,然后把黑色...luajit只支持lua 5.1语言,而且现在已经更新了。

14.3K70

C语言return函数

关于 void main C 和 C++ 中,接收任何参数也返回任何信息的函数原型为“void foo(void);”。...如果你有兴趣,也可以把 main 函数的返回值类型改成非 int 类型(如 float),重新编译执行“a && dir”,看看会出现什么情况,想想为什么会出现那样的情况。...因为不是标准,所以并非所有编译器都支持,故而移植性差,推荐使用。 到了这里,你应该了解为什么主函数定义为 int返回类型,而且函数体里面有return 0;这个语句了吧。...……        return 0;   }   函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。...l          返回类型是结构类型的函数中,return应该是结构的一个实例对象。 总之,函数定义为什么样的返回类型,该函数中return就应该是相应类型的值。

3.2K10
领券