Lua语言学习之协程

coroutine

协程(coroutine),即协同程序,它与线程差不多,也就是一条执行序列,拥有自己独立的栈、

局部变量和指令指针,同时又与其他协程共享全局变量和其他大部分东西。从概念上讲,线程与协程

的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协程却需要彼此协作地运行。

也就是说,一个具有多个协程的程序在任意时刻只能运行一个协程,并且正在运行的协同程序只会在其

显示地要求挂起时,它的执行才会暂停。

Lua 将所有关于协程的函数放置在一个名为 “ coroutine ”的 table 中。

下面介绍该 table 中操作协程的几个函数:

1、create 函数:创建 coroutine ,它只有一个参数,即一个函数。

该函数的代码就是协程所需执行的内容。create 会返回一个 thread 类型的值,用以表示新的协程。

通常 create 的参数是一个匿名函数,如:

co = coroutine.create ( function ( ) print " hi, co " end )

print ( co ) ----> thread: 0x8071d98

2、status 函数:检查协程的状态

一个协程可以处于四种不同的状态:挂起(suspended)、运行(running)、死亡(dead)和

正常(normal)。当创建一个新的协程时,它处于挂起状态,需要手动启动一个协程。

3、resume函数:用于启动或再次启动一个协程的执行,并将其状态由挂起改为运行:

coroutine.resume ( co ) -----> hi, co

协程执行之后便终止了,然后它就处于死亡状态,也就再也无法返回了。

print ( coroutine.status ( co ) ) ---> dead

resume 还可以传不定参数:resume ( co [ , val1, ... ] )

Starts or continues the execution of coroutine co

The first time you resume a coroutine, it starts running its body. 

The values val1, ··· are passed as the arguments to the body function. 

第一次启动协程,参数会传给所要执行的函数体。

If the coroutine has yielded, resume restarts it; the values val1, ··· are passed 

as the results from the yield.

如果协程已经 yield 了,再次启动该协程时,会把 yield 函数中返回的结果当作

参数传入 resume 函数。

If the coroutine runs without any errors, resume returns true plus any values 

passed to yield (if the coroutine yields) or any values returned by the 

body function (if the coroutine terminates). 

当一个协程结束时,它的主函数所返回的值都将作为对应 resume 的返回值:

co = coroutine.create ( function ( ) return 6, 7 end )

print ( coroutine.resume( co ) )  ----> true 6 7

If there is any error, resume returns false plus the error message.


4、yield 函数:让一个运行中的协程挂起,之后还可以恢复它的运行。

Suspends the execution of the calling coroutine. 

The coroutine cannot be running a C function, a metamethod, or an iterator. 

Any arguments to yield are passed as extra results to resume.

5、running 函数

Returns the running coroutine, or nil when called by the main thread.

能得到正在运行的协程,如:

co = coroutine.create(function() print(coroutine.running()) end )
coroutine.resume(co123)
thread: 003CD978

例子:

[plain]  view plain copy
  1. function foo (a)  
  2.     print("foo", a)  -- foo 2  
  3.     return coroutine.yield(2 * a) -- return: a , b  
  4. end  
  5.    
  6. co = coroutine.create(function (a , b)  
  7.     print("co-body", a, b) -- co-body 1 10  
  8.     local r = foo(a + 1)  
  9.        
  10.     print("co-body2", r)  
  11.     local r, s = coroutine.yield(a + b, a - b)  
  12.        
  13.     print("co-body3", r, s)  
  14.     return b, "end"  
  15. end)  
  16.           
  17. print("main", coroutine.resume(co, 1, 10)) -- true, 4  
  18. print("------")  
  19. print("main", coroutine.resume(co, "r")) -- true 11 -9  
  20. print("------")  
  21. print("main", coroutine.resume(co, "x", "y")) -- true 10 end  
  22. print("------")  
  23. print("main", coroutine.resume(co, "x", "y")) -- false cannot resume dead coroutine  
  24. print("------")  
结果如下:

[plain]  view plain copy
  1. >lua -e "io.stdout:setvbuf 'no'" "cur.lua"   
  2. co-body 1   10  
  3. foo 2  
  4. main    true    4  
  5. ------  
  6. co-body2    r  
  7. main    true    11  -9  
  8. ------  
  9. co-body3    x   y  
  10. main    true    10  end  
  11. ------  
  12. main    false   cannot resume dead coroutine  
  13. ------  
  14. >Exit code: 0  


6. wrap 函数

Creates a new coroutine, with body ff must be a Lua function.

 Returns a function that resumes the coroutine each time it is called. 

Any arguments passed to the function behave as the extra arguments to resume

Returns the same values returned by resume, except the first boolean. 

In case of error, propagates the error.

这个函数和 create 类似,都是创建一个协程,不同的是wrap 函数创建的协程会返回一个

函数,这个函数会启动一次该协程。

例如,编写一个迭代器:

function permgen ( a, n )
	n = n or # a
	if n <= 1 then
		coroutine.yield( a )
	else
		for i = 1,n do
			a[n], a[i] = a[i] , a[n]
			permgen( a, n - 1 )
			a[n], a[i] = a[i] , a[n]
		end
	end
end


function permutations ( a )
	local co = coroutine.create( function ( ) permagen ( a ) end )
	return function ( )
		local code, res = coroutine.resume( co )
		return res
	end
end

permutations 函数可以用 wrap 函数来写:

function permutations ( a )
	return coroutine.wrap( function ( ) permgen ( a ) end )
end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值