分时调度协程脚本语言

今天的主角是一个分时调度协程的脚本语言——Melang。这篇文章主要介绍Melang的协程使用。关于Melang的安装,可以参考安装文档。

之所以强调分时调度,其实是为了强调Melang协程和其他语言协程的差异。在Lua、Go中,当某一个协程运行时,如果不调用某些特定库函数或者yield之类的函数,那么当前协程将一直持有CPU执行权,也就导致了其他协程或者I/O事件或者其他类型事件无法被响应,进而导致整个系统出现运行异常的情况。诚然,经过精密的设计,可以完全避免这类问题。但也会给开发者增加维护和学习成本。而Melang的每个协程,都是运行一段时间后被解释器强制中断挂起,让其他协程或者I/O事件等得以运行和处理。

在Melang中,每一个协程就是一个脚本任务,它可能是文件,也可能只是一段代码片段。每一个协程都有相对独立的运行上下文(也就是相对独立的运行环境),但也允许通过脚本库函数使得多个协程间进行通信。

下面给出两种启用多个协程的方法:

方法1

//a.m
sys = Import('sys');

while (true) {
  sys.print('a');
}
//b.m
sys = Import('sys');

while (true) {
  sys.print('b');
}

假设我们有这两个协程示例(也是两个文件),它们的功能就是死循环向终端输出ab

我们可以通过如下命令在单个线程内运行这两个协程:

melang a.m b.m

可以看到他们的输出大致如下:

...
a
a
a
a
a
a
a
a
...
b
b
b
b
b
b
b
...
a
a
a
a
a
a
a
a
...

由于lua等老牌支持协程的语言实现缘故,可能一些读者会怀疑我在sys.print中加入了强制切换协程的代码,那么可以使用如下示例自行验证一下。

//a.m
while (true){}
//b.m
while (true){}
//c.m
sys = Import('sys')
while (true) {
  sys.print('c');
}
melang a.m b.m c.m

方法2

使用内置函数Eval拉起协程。

我们首先假设同一路径下的有两个文件名为:a.mb.m。当然,实际使用中,可以放在不同路径下,这里只是为了演示方便。

//a.m
sys = Import('sys');

Eval('b.m');

while (true) {
  sys.print('a');
}
//b.m
sys = Import('sys');

while (true) {
  sys.print('b');
}

然后执行如下命令:

melang a.m

我们可以得到与方法1中第一个示例一样的输出。

Eval还有另一种用法,示例如下:

//a.m
sys = Import('sys');

Eval('sys = Import("sys"); while (true) {sys.print("b");}', nil, true);

while (true) {
  sys.print('a');
}

然后执行

melang a.m

依旧可以得到一样的输出效果。

事实上,上述的两种方法都只是对脚本解释器提供的API的不同封装。我们也可以自己开发其他的协程启动形式。

感谢阅读!

感兴趣的读者可以访问Github仓库或者官方文档了解更多内容。

你可能感兴趣的:(c语言,经验分享,程序人生,linux,开发语言,后端,开源)