β

一个简单、轻量的 Linux 协程实现

Heiher's Blog 128 阅读

HevTaskSystem 是一个简单的、轻量的多任务系统(或称协程),它工作于 Linux 平台,I/O event poll 基于 Epoll。

协程其实是一种古老的技术,协程有这么几个特点:
1. 协程是一个并发运行的多任务系统,一般由一个操作系统线程驱动。
2. 协程任务元数据资源占用比操作系统线程更低,且任务切换开销小。
3. 协程是任务间协作式调度,即某一任务主动放弃执行后进而调度另外一任务投入运行。

与异步、非阻塞式I/O模型类似,协程技术同样适用于处理海量的并发I/O任务,而且还不会像异步方式使业务代码逻辑支离破碎。

基本信息
HevTaskSystem 目前开放了四个类:HevTaskSystem、HevTask、HevTaskPoll 和 HevMemoryAllocator。
HevTaskSystem 是协程任务系统,管理、调度众多的 HevTask 实例运行。由单一操作系统线程驱动,多个线程可并行驱动多套任务系统。
HevTask 是协程任务,实例可加入某一 HevTaskSystem 中调度运行。
HevTaskPoll 是提供了 poll 兼容的系统调用。
HevMemoryAllocator 是一个内存分配器接口,其后端有两套实现:
* 原始分配器,等价于 malloc/free。
* Slice 分配器,按分配大小限量缓存的分配器,缓存替换算法是 LRU。

Public API
TaskSystem – hev-task-system.h
Task – hev-task.h
TaskPoll – hev-task-poll.h
MemoryAllocator – hev-memory-allocator.h

简单示例
该示例演示了在主线程上运行一个协程任务系统,并创建两个独立的协程任务,分别以不同的优先级运行各自的入口函数。各自的入口函数中各循环2次,每次打印一个字符串并 yield 释放CPU 触发调度切换。


/*
 ============================================================================
 Name        : simple.c
 Author      : Heiher 
 Copyright   : Copyright (c) 2017 everyone.
 Description :
 ============================================================================
 */

#include 

#include 
#include 

static void
task_entry1 (void *data)
{
        int i;

        for (i=0; i<2; i++) {
                printf ("hello 1\n");
                /* 主动放弃执行,yield 函数会触发重新调度选取另一任务投入执行 */
                hev_task_yield (HEV_TASK_YIELD);
        }
}

static void
task_entry2 (void *data)
{
        int i;

        for (i=0; i<2; i++) {
                printf ("hello 2\n");
                hev_task_yield (HEV_TASK_YIELD);
        }
}

int
main (int argc, char *argv[])
{
        HevTask *task;

        /* 在当前线程上初始化 task system */
        hev_task_system_init ();

        /* 创建一个新的 task,栈空间采用默认大小 */
        task = hev_task_new (-1);
        /* 设置该 task 的优先级为 1 */
        hev_task_set_priority (task, 1);
        /* 将该 task 放入当前线程的 task system中,任务人口函数为 task_entry1
         * task_entry1 并不会在 hev_task_run 执行后立即调用,需等到该 task 被调度。
         */
        hev_task_run (task, task_entry1, NULL);

        task = hev_task_new (-1);
        hev_task_set_priority (task, 0);
        hev_task_run (task, task_entry2, NULL);

        /* 运行当前线程上相关的 task system,当无任务可调度时该函数返回 */
        hev_task_system_run ();

        /* 销毁当前线程上相关的 task system */
        hev_task_system_fini ();

        return 0;
}

Over!

作者:Heiher's Blog
Across the great firewall we can reach every corner in the world.
原文地址:一个简单、轻量的 Linux 协程实现, 感谢原作者分享。

发表评论