在Lu脚本中使用协程

在Lu脚本中使用协程

欢迎访问:http://www.forcal.net/

最近,在Lu脚本中增加了协程支持。

如果Lu表达式(函数)中使用了函数yield,该表达式称为一个协程(coroutine)。协程不能递归运行,只有这一个限制。Lu协程有4种状态:正常、运行、挂起、 终止。正常态是可以运行但还没有运行的状态;终止态协程是不能运行的,如果运行将返回nil。与协程相关函数有5个:

    yield:挂起协程并立即返回表达式(函数)的值。 
    status:查询表达式(包含协程)的状态。 
    abort:中止挂起的协程,此时协程处于正常态。 
    terminate:终止协程,协程处于终止态,不能运行。 
    resume:重启一个终止的协程,协程转为正常态。

详细说明:

    28.29 查询表达式(包含协程)状态 status(p):

    p是一个表达式句柄。正常返回一个整数表示表达式状态:0:普通表达式;1:普通表达式正在运行;2:普通表达式递归运行;5:协程;6:协程正在运行;7:协程挂起;8:协程终止。p非法时返回nil。

    28.30 中止挂起的协程 abort(p):

    p是一个协程句柄,正处于挂起状态。协程中止后,可以再次从头开始执行。操作成功返回true,否则返回false。

    28.31 终止协程 terminate(p):

    p是一个协程句柄,处于正常等待运行状态或者挂起状态。协程终止后将不能执行,执行时总返回nil。操作成功返回true,否则返回false。

    28.32 重启一个终止的协程 resume(p):

    p是一个协程句柄,正处于终止状态,重启后可以运行。操作成功返回true,否则返回false。

 

例子1:

f(x:i)= i=0, while{(i++, i<=5), yield(i)}, 888;
f[0]; f[0]; f[0]; f[0]; f[0]; f[0]; f[0]; f[0];

结果(返回888时协程转为了正常态):

1
2
3
4
5
888
1
2

例子2:协程状态转换

f(x:i)= i=0, while{(i++, i<=5), yield(i)}, 888;
f[0]; f[0]; status[@f]; f[0]; abort[@f]; f[0]; terminate[@f]; status[@f]; f[0]; resume[@f]; f[0]; f[0]; f[0];

结果(对照status、abort、terminate、resume等函数的返回值很容易理解以下结果):

1
2
7
3
true
1
true
8
nil
true
1
2
3

例子3:生产者与消费者

!!!using["sys"];
生产者(x:pp,k,i:p)= //自变量x仅用于避免该函数自动执行
    p=nil,          //p是模块变量,用于传递数据
    pp=lu[2,"aaa",6], //pp存放数据
    k=len(pp), i=0,
    while{i<k,
        o["\r\n---生产者---\r\n"],   //打印所在位置
        if{isnil(p), p=pp[i++], o["\r\n---生产者发送数据  ", p, "\r\n"]},  //p=nil时发送一个数据
        yield(true) //挂起协程
    };
消费者(x:i:p)= //自变量x仅用于避免该函数自动执行
    i=0,       //控制变量,i为偶数时消费者才消费
    while{true,
        o["\r\n---消费者---\r\n"], //打印所在位置
        if[++i%2, yield(true)],    //i为奇数时挂起协程
        if{!isnil(p), o["\r\n---消费者输出数据  ", p, "\r\n"], p=nil}, //p!=nil时输出一个数据
        if[status(@生产者)==8, break()],    //如果生产者终止,消费者就退出
        yield(true) //挂起协程
    };
main()=
    while{true,
        o["\r\n---main---\r\n"],   //打印所在位置
        生产者[0],
        if[status(@生产者)==5, terminate(@生产者)],  //如果生产者结束,就终止生产者
        消费者[0],
        if[status(@消费者)==5, break()]  //如果消费者结束,就退出
    };


结果:

---main---

---生产者---

---生产者发送数据  2

---消费者---

---main---

---生产者---

---消费者输出数据  2

---main---

---生产者---

---生产者发送数据  aaa

---消费者---

---消费者输出数据  aaa

---main---

---生产者---

---生产者发送数据  6

---消费者---

---main---

---消费者输出数据  6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值