吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 1819|回复: 20
上一主题 下一主题

[系统底层] 手把手实现一个协程/时间片轮转调度

[复制链接]
跳转到指定楼层
楼主
JuncoJet 发表于 2019-11-8 14:50 回帖奖励
前言
其实是这样的,前不久突发奇想的想实现一个动画时钟。用的是经典的动画架构,两个线程分别负责渲染和数据运算。
但是呢,如果需要移植到单片机或者其他的低级环境(没有多线程),只能重新实现。不过还有一个办法,就是使用协程。

协程是啥(内容直接 C-c,C-v)
协程(Coroutine)编译器级的,进程(Process)和线程(Thread)操作系统级的
进程(Process)和线程(Thread)是os通过调度算法,保存当前的上下文,然后从上次暂停的地方再次开始计算,重新开始的地方不可预期,每次CPU计算的指令数量和代码跑过的CPU时间是相关的,跑到os分配的cpu时间到达后就会被os强制挂起,开发者无法精确的控制它们。
协程(Coroutine)是一种轻量级的用户态线程,实现的是非抢占式的调度,即由当前协程切换到其他协程由当前协程来控制。目前的协程框架一般都是设计成 1:N 模式。所谓 1:N 就是一个线程作为一个容器里面放置多个协程。那么谁来适时的切换这些协程?答案是有协程自己主动让出 CPU,也就是每个协程池里面有一个调度器,这个调度器是被动调度的。意思就是他不会主动调度。而且当一个协程发现自己执行不下去了(比如异步等待网络的数据回来,但是当前还没有数据到),这个时候就可以由这个协程通知调度器,这个时候执行到调度器的代码,调度器根据事先设计好的调度算法找到当前最需要 CPU 的协程。切换这个协程的 CPU 上下文把 CPU 的运行权交个这个协程,直到这个协程出现执行不下去需要等等的情况,或者它调用主动让出 CPU 的 API 之类,触发下一次调度。

时间片轮转调度
我不知道这是啥啊,噗,只是听上去很帅的样子。和协程相似,应用于底层(操作系统)的话也许名字就叫这个吧。

实现协程的方式
平时的话,其实有很多选择的嘛。比如说 Arduino 玩家会常玩的 ProtoThreads,比较轻量级,使用的 C 语言宏写成,占用资源低,易于移植。还有Libco啥的,其实没用过(捂脸。主要是如果无法理解协程的话,用起来会不怎么得(dei第三声)力。和线程以及RTOS的多任务不同,程序执行过程中不会中断去执行另一个任务。如果阻塞的一个协程的话,可能导致程序无法正常的表达。
自己实现一个协程的话,有助于理解底层原理,以及了解他的弊端。在以后的使用中,可以规避掉这种不正确的使用,写出更优质的代码。


我画了个示意图,这个是我个人的理解啊,我也不保证是完全对的。欢迎拍板砖。

根据上面的图,我们可以这样设计程序。

代码实现的是两个print字符串的过程,一个是1秒一个是2秒。类似多线程的效果。可以看到实现的功能很OjbK。之后,可以应用此协程库,来写点厉害的东西。
(本协程库已开源 https://github.com/JuncoJet/simCoroutines


(动画帧数低,将就看,实际效果比这好多了)
这个是前些时候写的Cli的动画时钟,前言中提到的。我已经分别用多线程和自己写的协程来重新实现过了。两个版本都会打包,稍后可以附件中下载。




代码写的比较像Arduino中的代码,这样写有种亲切感,开开开玩笑。主要程序一旦运行就不会退出,结构很相似吧,所以就做了个模仿秀。

tgt[3]分别存储了3个协程触发的时间,程序loop中做时间轮询,时间到就触发代码块。
[C] 纯文本查看 复制代码
void loop(){//负责时间片轮转 
DWORD m=timeGetTime();
if(m>=tgt[0]||!tgt[0])showTime();//协程0,显示时间
if(m>=tgt[1]||!tgt[1])getTime();//协程1,获取时间
if(m>=tgt[2]||!tgt[2])change();//协程2,递增数值
Sleep(1);
}


delay确定了下一次的执行时间,
[C] 纯文本查看 复制代码
void delay(int t,int x){//负责更新时间 
	tgt[x]=(tgt[x]?tgt[x]:timeGetTime())+t;
}

第一次运行tgt为空的话直接用timeGetTime()的值,之后直接累加。如果继续使用timeGetTime()的话会被协程执行时间延误从而受到影响,为避免协程运行时间产生偏差,所以我采用直接累加的方式。
其他功能,下载附件后自行研究吧,本章主讲协程。这个代码只是举个栗子!

协程的好处
协程有三宝,双手和大脑(雾
协程占用资源低,可以应用于一些环境苛刻的地方,如大多数的8位单片机。
协程是一种(新的)程序的思想,单线程写着无聊了,可以尝试另一种写法。
协程还能应用于VB、Ruby(不黑你的假多线程)之类的无法完美支持多线程的程序中使用。

内容比较干,比较初级,欢迎大家留言深入讨论。

CliClock.zip

14.52 KB, 下载次数: 11, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 5吾爱币 +9 热心值 +4 收起 理由
wkgczx + 1 + 1 热心回复!
demo886 + 1 用心讨论,共获提升!
bestnike + 1 + 1 我很赞同!
Hmily + 6 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
泳诗 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| JuncoJet 发表于 2019-11-8 15:45 <
朱朱你堕落了 发表于 2019-11-8 15:42
大佬。这是什么编译器?没见过

C-Free(MinGW)啊
推荐
精英猛男 发表于 2019-11-11 10:03
虽然还看不懂,但是还是起来膜拜下高手,学习了。谢谢分享~!
沙发
朱朱你堕落了 发表于 2019-11-8 15:42
4#
apples1949 发表于 2019-11-8 15:51
膜拜膜拜
5#
q74330 发表于 2019-11-8 15:52
楼主小哥想表达什么,,看了半天,,小哥要照顾小白
6#
wakichie 发表于 2019-11-8 17:04
膜拜大佬啊
7#
bester 发表于 2019-11-8 19:00
大佬啥时候放点黑科技出来呀
8#
lep52 发表于 2019-11-9 06:58
学习一下,虽然看不懂
9#
章学诚 发表于 2019-11-9 11:07
大师级别,赞赞赞,学习了
10#
露哥爱破解 发表于 2019-11-10 09:14
看不懂 觉得很高大上
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:禁止回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2019-11-21 23:01

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表