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

news2024/11/20 0:28:40

在软件工程中,协程(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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MinIO 的 S3 over RDMA 计划: 为高速人工智能数据基础设施设定对象存储新标准

随着 AI 和机器学习的需求不断加速&#xff0c;数据中心网络正在迅速发展以跟上步伐。对于许多企业来说&#xff0c;400GbE 甚至 800GbE 正在成为标准选择&#xff0c;因为数据密集型和时间敏感型 AI 工作负载需要高速、低延迟的数据传输。用于大型语言处理、实时分析和计算机视…

怀旧游戏打卡清单(TODO)

感觉忙碌了好久好久&#xff0c;真的好想休息一下。。 整理一下将来休息时候的打卡清单&#xff0c;不工作了去个海边狂打游戏&#xff0c;想想就惬意啊。当然&#xff0c;最好找个work from home&#xff0c;去海边找个酒店上班。挣钱休息两不误。。。 能不能实现另说&#xf…

《Python制作动态爱心粒子特效》

一、实现思路 粒子效果&#xff1a; – 使用Pygame模拟粒子运动&#xff0c;粒子会以爱心的轨迹分布并运动。爱心公式&#xff1a; 爱心的数学公式&#xff1a; x16sin 3 (t),y13cos(t)−5cos(2t)−2cos(3t)−cos(4t) 参数 t t 的范围决定爱心形状。 动态效果&#xff1a; 粒子…

使⽤MATLAB进⾏⽬标检测

目录 数据准备定义模型并训练用测试集评估性能推理过程⼀⾏代码查看⽹络结构⼀⾏代码转onnx结语 ⼈⽣苦短&#xff0c;我⽤MATLAB。 Pytorch在深度学习领域占据了半壁江⼭&#xff0c;最主要的原因是⽣态完善&#xff0c;⽽且api直观易⽤。但谁能想到现在MATLAB⽤起来⽐Pytorch…

word-毕业论文的每一章节的页眉单独设置为该章的题目怎么设置

在Microsoft Word中&#xff0c;为毕业论文的每个章节设置不同的页眉&#xff0c;通常需要使用“分节符”来分隔各个章节&#xff0c;然后在每个章节中单独设置页眉。以下是详细步骤&#xff1a; 使用分节符 插入分节符&#xff1a; 将光标放在每个章节的末尾&#xff08;注意…

【简历】25届江苏二本JAVA简历:本末倒置,重点部分格式错误,不重要的写了一堆

简历总体说明 校招的第一法则就是必须要确定校招层次。 开发岗分为大中小厂&#xff0c;不同的层次对学校背景、时间点、项目和考点的要求都不太一样&#xff0c;所以必须要确定就业的层次。 这是一个25届二本同学的JAVA简历。 最近不知道怎么回事&#xff0c;看两份简历都…

字母异位词分组(java)

题目描述 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单shilie 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "n…

fpga spi回环

SPI设备间的数据传输之所以又被称为数据交换,是因为 SPI协议规定一个 SPI设备 不能在数据通信过程中仅仅只充当一个"发送者(Transmitter)“或者"接收者 (Receiver)”.在每个 Clock 周期内,SPI 设备都会发送并接收一个 bit 大小的数据(不管主 设备好还是从设备),相当于…

计算机网络-理论部分(二):应用层

网络应用体系结构 Client-Server客户-服务器体系结构&#xff1a;如Web&#xff0c;FTP&#xff0c;Telnet等Peer-Peer&#xff1a;点对点P2P结构&#xff0c;如BitTorrent 应用层协议定义了&#xff1a; 交换的报文类型&#xff0c;请求or响应报文类型的语法字段的含义如何…

路由器基本原理与配置

一 &#xff0c; 路由是什么&#xff1f; 从源主机到目标主机的转发过程&#xff1b; 二 &#xff0c; 路由器 &#xff08;1&#xff09;路由器的工作原理 路由器是一种三层设备&#xff0c;是使用IP地址寻址&#xff0c;实现从源IP到达目标IP地址的端到端的服务&#xff0c…

windows的WSL Ubuntu子系统重置root或其他用户的密码

思路&#xff1a;以管理员身份运行PowerShell&#xff0c;在命令行窗口重置密码 &#xff0c;不需要删除或重新安装Linux子系统。 1、以管理员身份运行PowerShell 2、用root用户启动Ubuntu&#xff0c;执行 wsl.exe --user root 3、重置密码&#xff0c;执行passwd username&…

autoDL微调训练qwen2vl大模型

autodl是一家GPU服务厂商&#xff0c;提供专业的GPU租用服务&#xff0c;秒级计费、稳定好用 先去autodl把官方的帮助文档看懂先 AutoDL帮助文档 autodl注册并登陆&#xff0c;充钱&#xff0c;根据自己的情况租用新实例 创建新实例后马上关机&#xff0c;因为有个省钱的办法…

9.2 使用haarcascade_frontalface_default.xml分类器检测视频中的人脸,并框出人脸位置。

1&#xff09;程序代码&#xff1a; # 2.使用haarcascade_frontalface_default.xml分类器检测视频中的人脸&#xff0c;并框出人脸位置 import cv2# 加载人脸检测的 Haar 级联分类器 face_cascade cv2.CascadeClassifier(./data/haarcascades/haarcascade_frontalface_defaul…

K8S containerd拉取harbor镜像

前言 接前面的环境 K8S 1.24以后开始启用docker作为CRI&#xff0c;这里用containerd拉取 参考文档 正文 vim /etc/containerd/config.toml #修改内容如下 #sandbox_image "registry.aliyuncs.com/google_containers/pause:3.10" systemd_cgroup true [plugins.…

ARM64环境部署EFK8.15.3收集K8S集群容器日志

环境规划 主机IP系统部署方式ES版本CPU架构用户名密码192.168.1.225Ubuntu 22.04.4 LTSdockerelasticsearch:8.15.3ARM64elasticllodyi4TMmZD ES集群部署 创建持久化目录(所有节点) mkdir -p /data/es/{data,certs,logs,plugins} mkdir -p /data/es/certs/{ca,es01}服务器…

前端小练习——星辰宇宙(JS没有上限!!!)

前言&#xff1a;在刚开始学习前端的时候&#xff0c;我们会学习到前端三件套中的JavaScript&#xff0c;可能那时候读者没有觉得JavaScript这个语言有多么的牛逼&#xff0c;本篇文章将会使用一个炫酷的案例来刷新你对JavaScript这个语言的认知与理解。 ✨✨✨这里是秋刀鱼不做…

图文教程 | 2024年IDEA安装使用教程,JDK简易下载方法

前言 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 目录 一、IDEA安装 二、激活 三、JDK安装 四、JDK环境配置 五、验证 一、IDEA安装 进入官网下载&#xff1a; Other…

【阅读记录-章节2】Build a Large Language Model (From Scratch)

目录 2.Working with text data2.1 Understanding word embeddings2.2 Tokenizing text通过一个简单的实验来理解文本的词元化概念关键概念 2.3 Converting tokens into token IDs实现分词器类&#xff08;Tokenizer Class&#xff09;应用分词器测试文本的编码与解码通过分词器…

已有docker增加端口号,不用重新创建Docker

已有docker增加端口号&#xff0c;不用重新创建Docker 1. 整体描述2. 具体实现2.1 查看容器id2.2 停止docker服务2.3 修改docker配置文件2.4 重启docker服务 3. 总结 1. 整体描述 docker目前使用的非常多&#xff0c;但是每次更新都需要重新创建docker&#xff0c;也不太方便&…

网页作业9

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>服务中心</title><style>* {margin:…