在Lu脚本中使用协程

来源:互联网 发布:图像故障诊断算法 编辑:程序博客网 时间:2024/04/30 12:26

在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

0 0
原创粉丝点击