(Lua notes): Lua coroutine

 

Lua coroutine

Getting Started Case 1

  • Create and start the coroutine
    • Define the coroutine function coroutine.create()
    • Start the coroutine.resume()
co=coroutine.create(   --创建协程函数
	function (a,b)
		print(a+b)
	end
)

coroutine.resume(co,20,30)  --启动协程函数

Getting started case 2

  • Create a coroutine through coroutine.wrap() and start it
co=coroutine.wrap(
	function (a,b)
		print(a+b)
	end
)

co(20,30)

Getting started case 3

  • Use coroutine.yield() to suspend the coroutine halfway, and start again, the second time coroutine.resume() does not need to pass parameters
co=coroutine.create(
	function (a,b)
		print(a+b)
		coroutine.yield()
		print(a-b)
	end
)
coroutine.resume(co,1,2)
print("I'm here!")
coroutine.resume(co)

输出:
3
I'm here!
-1

Getting Started Case 4

  • coroutine.status()
  • There are three states of coroutine: dead, suspended, running
co=coroutine.create(
	function (a,b)
		print(a+b)
		print(coroutine.status(co))   --running
		print(a+b)
		coroutine.yield()
		print(a-b)
	end
)
print(coroutine.status(co))  --此时未启动协程,suspended

coroutine.resume(co,10,20) 

print(coroutine.status(co))  --suspended

print("I'm here!")  

coroutine.resume(co) 

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

Getting Started Case 5

  • coroutine.running()
  • Return the running coroutine. A coroutine is a thread. When running is used, it returns a corouting thread number.
co=coroutine.create(
	function (a,b)
		print( coroutine.running() )  --thread: 00A78110
		coroutine.yield()
		print(a-b)
	end
)
print( coroutine.running() )  --nil

coroutine.resume(co,10,40)

print("I'm here!")

coroutine.resume(co)

Getting Started 6

  • The coroutine can return multiple values. The first value is a Boolean value, which indicates whether the coroutine is started successfully, and the return value of the coroutine function is the following
co=coroutine.create(
	function (a,b)

		coroutine.yield(a*b,a/b)

		return a%b,a/b+1
	end
)
res1,res2,res3 = coroutine.resume(co,10,40)
print(res1,res2,res3)  --true	400	0.25

print("I'm here!")

res1,res2,res3 = coroutine.resume(co)
print(res1,res2,res3)  --true	10	1.25

to sum up

method description
coroutine.create() Create coroutine, return coroutine, the parameter is a function, when used in conjunction with resume, the function call is awakened
coroutine.resume() Restart coroutine and use it with create
coroutine.yield() Suspend coroutine, set coroutine to suspended state, this can have many useful effects in conjunction with resume
coroutine.status() View the status of coroutine
Note: There are three statuses of coroutine: dead, suspended, and running. Please refer to the following program for specific when there is such a status
coroutine.wrap() Create a coroutine and return a function. Once you call this function, enter the coroutine and repeat the create function
coroutine.running() Return the running coroutine. A coroutine is a thread. When running is used, it returns a corouting thread number.
  • Coroutine is implemented as a thread at the bottom.
  • When a coroutine is created, an event is registered in the new thread.
  • When the resume trigger event is used, the coroutine function of create is executed. When yield is encountered, the current thread is suspended, waiting for the resume trigger event again.

Comprehensive case

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end
 
co = coroutine.create(function (a , b)
    print("第一次协同程序执行输出", a, b) -- co-body 1 10
    local r = foo(a + 1)
     
    print("第二次协同程序执行输出", r)
    local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入
     
    print("第三次协同程序执行输出", r, s)
    return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
end)
        
print("main", coroutine.resume(co, 1, 10)) -- true, 4

print("main", coroutine.resume(co, "r")) -- true 11 -9

print("main", coroutine.resume(co, "x", "y")) -- true 10 end

print("main", coroutine.resume(co, "x", "y")) -- false cannot resume dead coroutine
  • The above example is continued as follows:
    • Call resume to wake up the cooperative program. The resume operation returns true if it succeeds, otherwise it returns false;
    • Cooperative program operation;
    • Run to the yield statement;
    • Yield suspends the collaborative program, and the first resume returns; (note: here yield returns, and the parameter is the parameter of resume)
    • The second time of resume, wake up the cooperative program again; (note: in the resume parameters, except for the first parameter, the remaining parameters will be used as yield parameters) yield return;
    • The cooperative program continues to run;
    • If the used co-program continues to run and continues to call the resume method after completion, the output: cannot resume dead coroutine
    • The powerful combination of resume and yield is that resume is in the main process, and it transfers the external state (data) to the inner part of the collaborative program; while yield returns the internal state (data) to the main process.
  • Producer-consumer problem

local newProductor

function productor()
     local i = 0
     while true do
          i = i + 1
          send(i)     -- 将生产的物品发送给消费者
     end
end

function consumer()
     while true do
          local i = receive()     -- 从生产者那里得到物品
          print(i)
     end
end

function receive()
     local status, value = coroutine.resume(newProductor)
     return value
end

function send(x)
     coroutine.yield(x)     -- x表示需要发送的值,值返回以后,就挂起该协同程序
end

-- 启动程序
newProductor = coroutine.create(productor)
consumer()

输出:
1    2    3    4    5    6    7    8    9    10    11    12    13    ...

Guess you like

Origin blog.csdn.net/baidu_41388533/article/details/108512181