深入解析C++20协程的原理和应用
C++20标准引入了无栈协程,它与有栈协程和线程在性能和内存管理上有所不同。无栈协程的切换成本类似于函数调用,而有栈协程则需要较大的堆内存,存在栈溢出风险和内存浪费。C++20选择无栈协程的原因包括:无栈协程不占用额外栈空间,避免了栈溢出风险;性能上虽不如线程轻量,但在某些场景中更具优势。无栈协程是普通函数的推广,它可以暂停和恢复执行,允许在任意时刻恢复函数体,提供了更灵活的控制。C++20中的协程通过co_await、co_yield和co_return等关键字定义,编译器会生成相应代码来实现协程功能。协程对象包括协程帧、promise对象、coroutine return object和std::coroutine_handle等,它们协同工作,使得开发者能够完全控制协程行为。示例中,通过co_await,协程被调度到线程中,展示了协程的创建、挂起、等待任务结束和销毁的过程。C++20协程的灵活性和控制能力使得它在多种场景中展现出强大潜力
Lua协程(Coroutine)
协程是一种具备独立执行状态的程序片段,拥有自己的局部变量、栈和指令指针,同时与其它协程共享全局变量和其他资源。相较于线程,协程在任何时刻只能执行一个,且在明确指令下才会暂停执行。协程状态包括四种:运行、等待、挂起和死亡。创建协程使用`coroutine.create`函数,传入待执行的匿名函数,返回新协程。新协程默认处于等待状态,需通过`coroutine.resume`启动运行。协程的关键在于`yield`函数,它能挂起当前协程,等待`resume`函数恢复执行。通过`resume`,协程执行至`yield`处暂停,再继续执行。此特性使得协程实现非阻塞式异步编程。协程运行完毕后进入死亡状态,调用`resume`无法再次执行。当协程发生错误时,调用`resume`和`pcall`一样,运行在保护模式下,错误被隐藏,而非抛出。除了`create`,`wrap`函数同样用于创建协程,返回值为函数,若协程内发生错误,将终止协程并抛出错误
Contiki的内核分析-协程机制(一)
本文深入解析Contiki内核中的协程机制,以过程事件模型中的过程机制为核心。首先,回顾了事件机制的原理,进而展开分析Contiki的过程机制。过程机制实质上是协程调度机制,使用2个字节的变量保存“栈环境”,所有过程以链表形式保存。官方称其为protothread,实际上协程是对它的更好诠释。为了理解Contiki中的协程逻辑,分为两部分进行阐述:协程逻辑与协程实现。本篇集中于协程逻辑层面,下篇则深入探讨协程语法实现。Contiki的协程类型定义被简化,使得代码清晰明了。执行process_init和process_start函数,使etimer_process开始工作。这两个函数主要任务包括初始化过程链表、置零最小未使用事件、归零事件循环队列首尾指针等。process_start函数重点在于检查重复插入过程,并插入过程到链表,设置初始参数,以头插法插入。执行process_post_synch并传入PROCESS_EVENT_INIT事件,意味着该过程会立即执行
Go面试官:什么是协程?协程和线程的区别和联系?
大家好,我是煎鱼。在我的Go读者交流群里出现了许多小伙伴在讨论自己面试过程中所遇到的一些Go面试题。今天的男主角,是工程师的必修技能,那就是“什么是协程,协程和线程的区别和联系?”既要理解线程,还要讲解协程,并且诠释两者间的区别,但是由于提到线程,就必然涉及进程,因此本文将会同时梳理介绍“进程、协程、协程”三者的随笔知识。希望能引发大家的一些思考。进程进程是什么进程是操作系统对一个正在运行的程序的一种抽象,进程是资源分配的最小单位。为什么有进程为什么会有”进程“呢?说白了还是为了合理压榨CPU的性能和分配运行的时间片,不能“闲着“。在计算机中,其计算核心是CPU,负责所有计算相关的工作和资源。单个CPU一次只能运行一个任务。如果一个进程跑着,就把唯一一个CPU给完全占住,那是非常不合理的。那为什么要压榨CPU的性能?因为CPU实在是太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备则更是望尘莫及
python中多进程+协程的使用以及为什么要用它
前面讲了为什么python里推荐用多进程而不是多线程,但是多进程也有其自己的限制:相比线程更加笨重、切换耗时更长,并且在python的多进程下,进程数量不推荐超过CPU核心数(一个进程只有一个GIL,所以一个进程只能跑满一个CPU),因为一个进程占用一个CPU时能充分利用机器的性能,但是进程多了就会出现频繁的进程切换,反而得不偿失。不过特殊情况(特指IO密集型任务)下,多线程是比多进程好用的。举个例子:给你200W条url,需要你把每个url对应的页面抓取保存起来,这种时候,单单使用多进程,效果肯定是很差的。为什么呢?例如每次请求的等待时间是2秒,那么如下(忽略cpu计算时间):1、单进程+单线程:需要2秒*200W=400W秒==1111.11个小时==46.3天,这个速度明显是不能接受的2、单进程+多线程:例如我们在这个进程中开了10个多线程,比1中能够提升10倍速度,也就是大约4.63天能够完成200W条抓取,请注意,这里的实际执行是:线程1遇见了阻塞,CPU切换到线程2去执行,遇见阻塞又切换到线程3等等,10个线程都阻塞后,这个进程就阻塞了,而直到某个线程阻塞完成后,这个进程才能继续执行,所以速度上提升大约能到10倍(这里忽略了线程切换带来的开销,实际上的提升应该是不能达到10倍的),但是需要考虑的是线程的切换也是有开销的,所以不能无限的启动多线程(开200W个线程肯定是不靠谱的)3、多进程+多线程:这里就厉害了,一般来说也有很多人用这个方法,多进程下,每个进程都能占一个cpu,而多线程从一定程度上绕过了阻塞的等待,所以比单进程下的多线程又更好使了,例如我们开10个进程,每个进程里开20W个线程,执行的速度理论上是比单进程开200W个线程快10倍以上的(为什么是10倍以上而不是10倍,主要是cpu切换200W个线程的消耗肯定比切换20W个进程大得多,考虑到这部分开销,所以是10倍以上)