关于 C/C++ 1Z(17)开源项目 openppp2 协同程式切换工作流

下述为开源项目 openppp2(github)构建工作在 C/C++ 17 的 stackful 有栈协同程式的工作流切换示意图:

在 openppp2 之中采用人工手动方式管理协同程式之间的切换,每个中断过程只是保存线程栈信息(如寄存器、当前#PC EIP)并且JMP相对寄存器长跳转到其它协同程序当前EIP位置。

它(协同程式)的切换开销是最小的,速度几乎是无损最快的,这好比人们在 C/C++ 之中用 “函数指针(地址标识符)” 去指向一个 C/C++ 函数,且通过函数指针进行调用,它本身就是长跳转的一种,区别只是少做了线程信息保存,及下个协同程序线程信息恢复的动作。

当然协同程式有一些是通过操作系统核心库API构建的有栈协同程式。

例如:

1、Windows NT平台使用:GetThreadContext、SetThreadContext 函数来构建的有栈协同切换。

2、Linux 平台上使用 ucontext.h 库函数:getcontext、setcontext、makecontext、swapcontext 函数来构建的有栈协同切换。

那么:此类有栈协同程式切换效能的确不行,某些人不要张口就来,不是真懂别乱逼逼。

但通过汇编语言构建的有栈协同程式,几乎不存在性能问题,单线程挂载百万个、千万个协同程式都可以,只要母鸡内存足够大,即可。

stackless 有栈协同程式不要来碰瓷效能,比协同程式切换效能,stackless 真不配跟 stackfull 协同程式比切换效能,若我们不懂这两个协同程式怎么实现的,还真有可能被XX们忽悠住,但可惜我们了解这两类协同程式底层是怎么构建的,当然也自行实现构建过两者,所以在这块还是有一定心得发言权的。

从上述的协同程式示意图之中,可以清晰的看到,在中断某一个协同程式时,会直接切换CPU到下一个协同程式(若有,否则为协同程式结束),而不是还会等待执行到。

但这有一个缺点,一旦某一个协同不按照正确流程切换,那么就会导致协程 deadline 问题,出现致命性故障,如流程中断、内存泄漏等问题层出不穷。

欲兼容性解决这类问题,那么必须引入一个协同程式调度器,但这并非必须的,长长构建多线程并行程式、对于协同程序非常了解的童鞋并不需要,因为这种调度切换的低级问题,不会在它们身上发生。

对于 C/C++ 编程语言来说首先采用 stackful 有栈协同程式,而不是使用 stackless 协同程式,即便是 C/C++ 20 标准提供的 stackless 协同程式,或者早前基于 boost 库提供的 stackless 协同程式。

关于在 go 语言之中,go 开启一个新的 stackless 协同程式,并不意味着立即运行,go 开发人员适用编译器关键字 go 开启新协同程式,能否立即运行取决于以下条件。

在 go 运行时仅只有单线程的情况下,它无法立即运行,而是需要等待当前正在执行协同程序到中断位置或结束时才运行,多线程情况下取决于那个闲置线程先获取到事件(基于系统 epoll、iocp、kqueue 构建的EDSM事件驱动状态机,运行时调度器)。

了解关于我们对于协程相关的一些看法,可以参见本人的以下文章:

C/C++ 如何正确的切换协同程序?(基于协程的并行架构)_c++怎么切换运行程序-CSDN博客

stackless or stackfull 协同程式(协程)?_boost stackless-CSDN博客

灌水玩玩 ChatGPT AIGC生成的有栈协同程序实现(例子)_任务协同 aigc-CSDN博客

C/C++ 11/14/17 有栈式协同程式的基础框架类库【关于】_c++11实现有栈对称协程库-CSDN博客

C++ 20标准协同程序(协程)基于编译器展开的 stackless 协程。-CSDN博客

关于 Go 协同程序(Coroutines 协程)、Go 汇编及一些注意事项。-CSDN博客

童鞋们可以好好理解在这些文章之中,我们关于协同程式的一些看法,那么童鞋们会对于协同程式有更深入的理解,不要去现在鱼龙混杂的逼乎(知乎)上看那些莫名其妙的想法及观点,国内技术相关这块大概就博客园、CSDN博客、看雪论坛比较好一点,其它建议还是算了把。

下述代码为 Linux 平台基于 ucontext.h 函数库实现的有栈协同程式切换(它很简明):

#include <ucontext.h>
#include <iostream>
#include <cstring>#define STACK_SIZE 1024*64ucontext_t mainContext, coroContext;void coroutineFunction() {std::cout << "Coroutine started" << std::endl;// 切换回主上下文swapcontext(&coroContext, &mainContext);std::cout << "Coroutine resumed" << std::endl;
}int main() {char stack[STACK_SIZE];getcontext(&coroContext);coroContext.uc_link = &mainContext;coroContext.uc_stack.ss_sp = stack;coroContext.uc_stack.ss_size = sizeof(stack);makecontext(&coroContext, (void (*)())coroutineFunction, 0);std::cout << "Main started" << std::endl;// 切换到协程上下文swapcontext(&mainContext, &coroContext);std::cout << "Main resumed" << std::endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/586795.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 集合进阶】单练集合顶层接口collction迭代器

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

枚举---算法

1、定义 枚举算法&#xff1a;也称之为穷举算法&#xff0c;这种算法就是在解决问题的时候去使用所有的方式去解决这个问题&#xff0c;会通过推理去考虑事件发生的每一种可能&#xff0c;最后推导出结果。优点&#xff1a;简单粗暴&#xff0c;它暴力的枚举所有可能&#xff…

hxp CTF 2021 - A New Novel LFI(新颖的解法)

一、环境 unbentu&#xff0c;docker https://2021.ctf.link/assets/files/includers%20revenge-25377e1ebb23d014.tar.xz 二、解析 PHP Filter 当中有一种 convert.iconv 的 Filter &#xff0c;可以用来将数据从字符集 A 转换为字符集 B &#xff0c;其中这两个字符集可以…

26版SPSS操作教程(初级第十四章)

前言 #由于导师最近布置了学习SPSS这款软件的任务&#xff0c;因此想来平台和大家一起交流下学习经验&#xff0c;这期推送内容接上一次第十三章的学习笔记&#xff0c;希望能得到一些指正和帮助~ 粉丝及官方意见说明 #针对官方爸爸的意见说的推送缺乏操作过程的数据案例文件…

【嵌入式学习】FreeRTOS day04.02

一、思维导图 二、练习 1.总结任务调度算法之间的区别&#xff0c;重新实现一遍任务调度算法的代码。 调度算法&#xff1a;抢占式调度&#xff1a;优先级高的任务可以打断低优先级任务的执行&#xff0c;适用于不同优先级任务的执行。 时间片轮换&#xff1a;分配时间片&…

论文精读--GPT4

现有的所有模型都无法做到在线学习&#xff0c;能力有限&#xff0c;而让大模型拥有一个tools工具库&#xff0c;则可以使大模型变成一个交互式的工具去协调调用API完成任务&#xff0c;同时GPT4还联网了&#xff0c;可以不断地更新自己的知识库 多模态模型&#xff0c;接受文…

加密/ 解密 PDF:使用Python为PDF文档设置、移除密码

在数字化时代&#xff0c;文档的安全性变得越来越重要。特别是对于包含敏感信息的PDF文件&#xff0c;确保其不被未经授权的人员访问或修改是至关重要的。本文将介绍如何使用Python在PDF文档中设置密码&#xff0c;以及如何移除已经设置的密码。 目录 PDF加密基础知识 Pytho…

简单而复杂的Python

Python是一种简单&复杂的编程语言。简单的时候可以到极致&#xff1a; print(hello world!)另一方面&#xff0c;Python 也具有许多复杂的语法特性&#xff0c;例如面向对象编程、装饰器、迭代器、生成器等等。这些特性使得 Python 适用于各种不同的编程任务和项目。 当我…

关于loop( ) 阻塞和非阻塞探究

一、SIR的补充 在上几篇博客中&#xff0c;有朋友私信问我&#xff0c;在ticker函数程序和中断服务程序&#xff08;ISR&#xff09;中写 物联网请求报错。怎么回事&#xff0c;在此解释。控制台如下 1.1解释 在使用 Ticker 函数和中断服务程序&#xff08;ISR&#xff09;时…

C++面向对象程序设计 - 访问对象中成员的3种方法

在C程序中访问对象的成员变量和成员函数&#xff0c;有三种方法&#xff1a; 通过对象名和成员运算符访问对象中的成员&#xff1b;通过指向对象的指针访问对象中的成员&#xff1b;通过对象的引用变量访问对象中的成员 在了解访问对象中成员的3种方法前&#xff0c;先了解下C…

蓝桥杯真题:单词分析

import java.util.Scanner; //1:无需package //2: 类名必须Main, 不可修改 public class Main{public static void main(String[]args) {Scanner sannernew Scanner(System.in);String strsanner.nextLine();int []anew int [26];for(int i0;i<str.length();i) {a[str.charA…