V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
monkeyNik
V2EX  ›  编程

分时调度协程脚本语言

  •  
  •   monkeyNik · 2023-12-09 00:05:02 +08:00 · 447 次点击
    这是一个创建于 385 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天的主角是一个分时调度协程的脚本语言——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 仓库或者官方文档了解更多内容。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2796 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 09:32 · PVG 17:32 · LAX 01:32 · JFK 04:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.