协程,以C和C#为例

一、协程的核心概念

协程(Coroutine)是一种用户态的轻量级并发模型,允许在单线程中通过​​协作式调度​​实现多个任务的交替执行。其核心特性包括:

  1. ​非抢占式切换​​:协程主动让出执行权,而非被系统强制中断。
  2. ​状态保存与恢复​​:每次挂起时保存局部变量和执行位置,恢复时从断点继续。
  3. ​低开销​​:上下文切换仅需修改寄存器,无需内核介入,性能比线程高10-100倍。
  4. ​适用场景​​:I/O密集型任务(如网络服务器)、游戏逻辑、状态机实现。
  5. 非阻塞​​:在单线程中模拟并发,避免线程切换开销。
  6. 灵活控制​​:开发者可手动定义暂停条件(如等待时间、帧间隔等)。

 

二、C语言实现协程的常见方法

1. ​​基于libco库的实现​​​​

特点​​:高性能协程库(微信开源),底层使用汇编保存寄存器状态,支持百万级协程并发。

#include <stdio.h>
#include "co.h"

void coroutine_a() {
    printf("协程A启动\n");
    co_yield();  // 主动让出CPU
    printf("协程A恢复\n");
}

void coroutine_b() {
    printf("协程B启动\n");
    co_yield();
    printf("协程B恢复\n");
}

int main() {
    stCoRoutine_t *co_a, *co_b;
    co_create(&co_a, NULL, coroutine_a);  // 创建协程
    co_create(&co_b, NULL, coroutine_b);
    
    co_resume(co_a);  // 启动协程A
    co_resume(co_b);  // 启动协程B
    
    // 再次恢复协程以执行后续代码    
    co_resume(co_a);    
    co_resume(co_b);
    
    co_eventloop(co_get_epoll_ct());  // 事件循环
    return 0;
}

编译命令​​:gcc -o demo demo.c -lco

 输出结果:

协程A启动
协程B启动
协程A恢复
协程B恢复
2.基于setjmp/longjmp的轻量级实现​​

​特点​​:无需外部库,但无法自动保存栈数据(需手动管理)

#include <setjmp.h>
#include <stdio.h>

jmp_buf main_env, co_env;

void coroutine() {
    printf("协程启动\n");
    if (!setjmp(co_env)) 
        longjmp(main_env, 1);  // 切换回主函数
    printf("协程恢复\n");
}

int main() {
    if (!setjmp(main_env)) {
        coroutine();
    } else {
        printf主函数恢复\n");
        longjmp(co_env, 1);  // 再次切换至协程
    }
    return 0;
}

 

三、C#协程的两种实现方式

1.基于迭代器(IEnumerator)的协程

​​​​适用场景​​:游戏开发(如Unity)、逐帧操作或需要精细控制执行流程的场景。​​

实现原理​​:使用yield return关键字定义暂停点,编译器自动生成状态机类。通过IEnumerator接口管理协程生命周期(如MoveNext()方法)

using System.Collections;
using UnityEngine;

public class CoroutineDemo : MonoBehaviour {
    void Start() {
        StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine() {
        Debug.Log("协程开始");
        yield return new WaitForSeconds(1);  // 暂停1秒[1,6](@ref)
        Debug.Log("1秒后继续执行");
        yield return null;                    // 等待下一帧[3](@ref)
        Debug.Log("下一帧执行");
    }
}

 

posted @ 2025-05-23 09:16  HelloMarsMan  阅读(471)  评论(0)    收藏  举报