说说软件工程中的“协程”

在软件工程中,协程(coroutine)是一种程序运行的方式,可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释:

一、协程的基本概念

  1. 定义:协程是一组序列化的子过程,用户能像指挥家一样调度交叉执行。协程既可以用单线程实现,也可以用多线程实现,但无论如何,其核心特点是能够并行执行且可以交换执行权
  2. 执行方式:在协程中,多个线程(或函数)可以并行执行,但只有一个线程(或函数)处于正在运行的状态,其他线程(或函数)都处于暂停态(suspended)。线程(或函数)之间可以交换执行权,即一个线程(或函数)执行到一半时,可以暂停执行,将执行权交给另一个线程(或函数),等到稍后收回执行权时,再恢复执行。

二、协程的特性

  1. 可控制性:协程能做到可被控制的发起子任务,这是与线程相比的一个重要区别。
  2. 轻量级:协程非常小、占用资源比线程还少。在JVM平台上,协程的本质就是一次方法的调用。
  3. 状态保留:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态。
  4. 用户级线程:协程不像线程和进程那样,需要进行系统内核上的上下文切换。协程的上下文切换是由开发人员决定的,因此更加高效。

三、协程的应用场景

  1. 网络编程:使用协程可以使网络编程更加简洁和高效,例如实现高性能的服务器程序。
  2. 并发编程:协程可以简化并发编程,提高代码的可读性和可维护性,减少并发编程的复杂性。
  3. 异步编程:协程可以简化异步编程,避免回调地狱和多线程的问题,提高代码的可读性和可维护性。
  4. 资源管理:协程可以更好地管理资源,避免资源泄露和内存泄漏的问题。
  5. 任务调度:协程可以用于实现轻量级的任务调度器,实现任务的调度和执行。
  6. 状态机:协程可以用于实现复杂的状态机,简化状态机的实现和维护。
  7. 数据处理:协程可以用于处理大量的数据,提高数据处理的效率和性能。

四、协程与线程、进程的对比

  1. 线程:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。线程切换需要操作系统内核的支持,因此开销较大。
  2. 进程:进程是操作系统分配资源的最小单位,它包含一组执行中的程序的指令、还有程序所使用到的数据和引用到的系统资源(如文件、内存等)。进程切换同样需要操作系统内核的支持,开销同样较大。
  3. 协程:协程是一种用户级的轻量级线程,它的上下文切换是由开发人员决定的,不需要操作系统内核的支持,因此开销较小。这使得协程在并发编程和异步编程中具有更高的效率和更好的可维护性。

综上所述,协程是一种高效的程序运行方式,在软件工程领域具有广泛的应用前景。

五,当前能直接实现协程的开发语言

 直接支持协程的开发语言包括但不限于以下几种:

  1. Golang(Go)
    • Go语言从设计之初就内置了对协程的支持,通过轻量级的goroutine实现。
    • Goroutine是Go语言中的一种并发体,它比线程更轻量,由Go运行时管理。
    • Go语言的协程特性使其在系统编程、高性能计算和云计算领域具有显著优势。
  2. Kotlin
    • Kotlin是一种在JVM上运行的静态类型编程语言,它支持协程作为一等公民。
    • Kotlin协程提供了一种在保持代码简洁性的同时实现高效并发的方法。
    • Kotlin协程特别适用于Android开发,以及需要在JVM上运行的其他应用程序。
  3. C#
    • C#是Microsoft开发的一种多范式编程语言,自某个版本开始引入了异步编程模式,包括async和await关键字,这些关键字可以视为协程的一种实现方式。
    • C#的协程特性使其特别适用于需要处理大量IO操作或需要高效并发处理的应用程序。
      using System;
      using System.Threading.Tasks;
      
      class Program
      {
          static async Task AsyncTask(int step, int delay)
          {
              await Task.Delay(delay); // 模拟异步操作
              Console.WriteLine($"Step: {step}");
          }
      
          static async Task CoroutineLikeExample()
          {
              for (int i = 0; i < 5; i++)
              {
                  await AsyncTask(i + 1, 1000); // 等待异步任务完成
              }
              Console.WriteLine("All steps completed.");
          }
      
          static void Main(string[] args)
          {
              CoroutineLikeExample().Wait(); // 等待异步方法完成(在Main方法中需要这样做,因为Main不能是异步的)
          }
      }

  4. Python
    • Python通过其内置的asyncio库支持异步编程,这可以看作是一种协程的实现方式。
    • 虽然Python的asyncio库不是传统意义上的协程,但它提供了一种编写异步代码的方法,使代码更加简洁和易于维护。
    • Python的协程特性在数据科学、机器学习、Web开发和自动化脚本等领域具有广泛应用。
  5. JavaScript
    • JavaScript通过其内置的async/await语法和Promise对象支持异步编程,这也可以看作是一种协程的实现方式(尽管在严格意义上它可能不是传统意义上的协程)。
    • JavaScript的协程特性使其在Web开发、全栈开发和实时应用等领域具有广泛应用。
  6. C++(C++20及以后)
    • C++20标准引入了协程支持,通过co_await、co_yield和co_return等关键字实现。
    • C++的协程特性使其在系统编程、高性能计算和实时系统等领域具有显著优势。 
#include <iostream>
#include <coroutine>
#include <memory>
#include <thread>
#include <chrono>

// 定义协程的返回类型和promise类型
struct MyTask {
    struct promise_type;
    using handle_type = std::coroutine_handle<promise_type>;

    struct promise_type {
        MyTask get_return_object() {
            return MyTask{handle_type::from_promise(*this)};
        }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { std::exit(1); }
    };

    handle_type coro;

    MyTask(handle_type h) : coro(h) {}
    ~MyTask() { if (coro) coro.destroy(); }

    void resume() {
        if (coro.done()) return;
        coro.resume();
        // 注意:在实际应用中,你可能需要在这里添加循环或条件检查来避免忙等待
    }
};

MyTask myCoroutine() {
    for (int i = 0; i < 6; ++i) {
        std::cout << "Step: " << i << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠1秒
        co_await std::suspend_always{}; // 暂停协程
    }
}

int main() {
    auto task = myCoroutine();

    // 模拟事件循环或任务调度器
    for (int i = 0; i < 6; ++i) {
        task.resume(); // 恢复协程的执行
        std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 简单的延迟,避免忙等待
    }

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【linux】进程等待与进程替换

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.进程等待系统调用获取子进程status常用宏使用示例 02.进程替换替换函数关键点解释&#xff1a;代码详细分析execvpe 函数的使用 01.进程等待 任何子进程&#xff0c;在退出的…

认证鉴权框架SpringSecurity-5--权限管理篇

上面两篇我们重点介绍了如何在代码上集成springSecurity&#xff0c;同时完成登录认证和token认证的过程。我们直到springSecurity处理能帮我们完成认证外&#xff0c;还可以帮助我们完成权限校验的工作&#xff0c;这篇我们来重点介绍下springSecurity是如何实现鉴权的。 一、…

RK3588开发板Android12-SDK更新通知

迅为RK3588开发板Android12 SDK升级至RK的android-12.1-mid-rkr14版本 内核版本&#xff1a;升级至 5.10.160 版本&#xff0c;提供更好兼容性和性能。 rkbin 版本&#xff1a;支持最新的 1.17 版本 bin 和 1.46 版本的 bl31。

stm32教程:OLED屏显示字母、汉字、图片工程讲解

早上好啊&#xff0c;大佬们&#xff0c;今天带来的是我们 stm32系列的第一个外设——OLED&#xff0c;相信大家对于OLED都不陌生了吧&#xff0c;这个可以说每一个项目里的必需品了&#xff0c;单片机离不开OLED就像西方离不开耶路撒冷。 在生活中&#xff0c;我们见到的OLED的…

力扣 LeetCode 28. 找出字符串中第一个匹配项的下标(Day4:字符串)

解题思路&#xff1a; KMP算法 需要先求得最长相等前后缀&#xff0c;并记录在next数组中&#xff0c;也就是前缀表&#xff0c;前缀表是用来回退的&#xff0c;它记录了模式串与主串(文本串)不匹配的时候&#xff0c;模式串应该从哪里开始重新匹配。 next[ j - 1 ] 记录了 …

我与Linux的爱恋:进程间通信 匿名管道

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 文章目录 匿名管道pipe 匿名管道 匿名管道&#xff08;Anonymous Pipes&#xff09;是Unix和类Unix操作系统中的一种通信机制&#xff0c;用于在两个进程之间传递数据。匿名…

Java之JDBC,Maven,MYBatis

前言 就是用来操作数据库的 1.JDBC快速入门 注意在使用前一定要导入jar包 在模块那里新建目录&#xff0c;新建lib&#xff0c;粘贴复制jar包&#xff0c;我这个jar设置的是模块有效 package test1017;import java.sql.Connection; import java.sql.DriverManager; import…

基于Matlab的碎纸片的自动拼接复原技术

碎纸片的自动拼接复原技术 摘要&#xff1a;破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成&#xff0c;准确率较高&#xff0c;但耗费大量人力财力及时间&#xff0c;效率很低。随着计算机技术的…

STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

使用 STM32 设计的较为复杂的物联网项目&#xff0c;包括智能家居控制系统&#xff0c;涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器&#xff1a;选择 STM32F4 系列微控制器&#xff0c;如 STM32F407ZGT6&#xff0c;具有高性能和丰富的外设资源。 传感器模块&#x…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST&#xff1f; > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放&#xff1f; 大流量 > 多个…

LPDDR4芯片学习(四)——DDR Training

一、ZQ Calibration DDR 学习时间 (Part B - 6)&#xff1a;DRAM ZQ 校正 - 知乎 (zhihu.com) 从原理上解释什么是DDR的ZQ校准&#xff1f; - 知乎 (zhihu.com) LPDDR4的训练(training)和校准(calibration)--ZQ校准(Calibration)_wonder_coole-腾讯云开发者社区 01 ZQ校准的…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…

鸿蒙实战:页面跳转

文章目录 1. 实战概述2. 实现步骤2.1 创建项目2.2 准备图片素材2.3 编写首页代码2.4 创建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 实战概述&#xff1a;本实战通过ArkUI框架&#xff0c;在鸿蒙系统上开发了一个简单的两页面应用。首页显示问候语和“下一页”按钮&…

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

深入理解 Spark 中的 Shuffle

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

常用在汽车PKE无钥匙进入系统的高度集成SOC芯片:CSM2433

CSM2433是一款集成2.4GHz频段发射器、125KHz接收器和8位RISC&#xff08;精简指令集&#xff09;MCU的SOC芯片&#xff0c;用在汽车PKE无钥匙进入系统里。 什么是汽车PKE无钥匙进入系统&#xff1f; 无钥匙进入系统具有无钥匙进入并且启动的功能&#xff0c;英文名称是PKE&…

人力资源招聘系统-提升招聘效率与质量的关键工具

在当今这个竞争激烈的商业环境中&#xff0c;企业要想在市场中立于不败之地&#xff0c;关键在于拥有高素质的人才队伍。然而&#xff0c;传统的招聘方式往往效率低下&#xff0c;难以精准匹配企业需求与人才特质&#xff0c;这无疑给企业的发展带来了不小的挑战。 随着科技的飞…

R语言贝叶斯分析:INLA 、MCMC混合模型、生存分析肿瘤临床试验、间歇泉喷发时间数据应用|附数据代码...

全文链接&#xff1a;https://tecdat.cn/?p38273 多模态数据在统计学中并不罕见&#xff0c;常出现在观测数据来自两个或多个潜在群体或总体的情况。混合模型常用于分析这类数据&#xff0c;它利用不同的组件来对数据中的不同群体或总体进行建模。本质上&#xff0c;混合模型是…

算法--解决二叉树遍历问题

第一 实现树的结构 class Node(): # 构造函数&#xff0c;初始化节点对象&#xff0c;包含数据和左右子节点 def __init__(self, dataNone): self.data data # 节点存储的数据 self.left None # 左子节点&#xff0c;默认为None self.rig…

华为eNSP:MSTP

一、什么是MSTP&#xff1f; 1、MSTP是IEEE 802.1S中定义的生成树协议&#xff0c;MSTP兼容STP和RSTP&#xff0c;既可以快速收敛&#xff0c;也提供了数据转发的多个冗余路径&#xff0c;在数据转发过程中实现VLAN数据的负载均衡。 2、MSTP可以将一个或多个VLAN映射到一个Inst…