4.25. Lua collaborative program (coroutine)

发布时间 : 2025-10-25 13:34:09 UTC      

Page Views: 10 views

4.25.1. What is coroutine? #

Lua collaborative programs (coroutine) are similar to threads: they have independent stacks, independent local variables, independent instruction pointers, and share global variables and most other things with other co-programs.

Collaboration is a very powerful feature, but it is also very complex to use.

4.25.2. The difference between threads and collaborative programs #

The main difference between threads and collaborative programs is that a program with multiple threads can run several threads at the same time, while collaborative programs need to run cooperatively with each other.

Only one collaborative program is running at any given time, and the runningcollaborative program is suspended only if it is explicitly asked to suspend.

A collaborative program is a bit like synchronous multithreading, and several threads waiting for the same thread lock are somewhat similar to collaboration.

Basic grammar #

Method

Description

coroutine.create

Create coroutine and return coroutine. The argument is a function, which wakes up the function call when used with resume.

coroutine.resume()

Restart coroutine for use with create

coroutine.yield()

Suspend coroutine and set coroutine to suspend state, which can have many useful effects when used with resume

coroutine.status()

View the status of coroutine

Note: there are three states of coroutine: dead,suspended,running. When there is such a status, please refer to the following program.

coroutine.wrap()

Create a coroutine and return a function. Once you call this function, you enter coroutine and repeat the create function.

coroutine.running()

Returns the running coroutine. A coroutine is a thread. When using running, it returns the thread number of a coroutine.

4.25.3. The following examples demonstrate the use of each of the above methods: #

Coroutine_test.lua file #

-- coroutine_test.lua file co = coroutine.create( function(i) print(i); end ) coroutine.resume(co, 1) -- 1 print(coroutine.status(co)) -- dead print("----------") co = coroutine.wrap( function(i) print(i); end ) co(1) print("----------") co2 = coroutine.create( function() for i=1,10 do print(i) if i == 3 then print(coroutine.status(co2)) --running print(coroutine.running()) --thread:XXXXXX end coroutine.yield() end end ) coroutine.resume(co2) --1 coroutine.resume(co2) --2 coroutine.resume(co2) --3 print(coroutine.status(co2)) -- suspended print(coroutine.running()) print("----------") 

The output of the above example is as follows:

1 dead ---------- 1 ---------- 1 2 3 running thread: 0x7fb801c05868 false suspended thread: 0x7fb801c04c88 true ---------- 

coroutine.running you can see it. The coroutine underlying implementation is a thread.

When create one coroutine an event is registered in the new thread.

When using resume to trigger an event create of coroutine the function is executed when encountered yield it means to suspend the current thread and wait for it to happen again resume trigger the event.

Let’s analyze a more detailed example:

Example #

function foo (a) print("foo function output", a) return coroutine.yield(2 * a) -- Returns the value of 2*a end co = coroutine.create(function (a , b) print("First collaborative program execution output", a, b) -- co-body 1 10 local r = foo(a + 1) print("Second collaborative program execution output", r) local r, s = coroutine.yield(a + b, a - b) -- The value of a and b is passed in the first call to the collaborative program print("Third collaborative program execution output", r, s) return b, "End collaborative program" -- The value of b is passed in the second call to the collaborative program end) print("main", coroutine.resume(co, 1, 10)) -- true, 4 print("--Divider----") print("main", coroutine.resume(co, "r")) -- true 11 -9 print("---Divider---") print("main", coroutine.resume(co, "x", "y")) -- true 10 end print("---Divider---") print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine print("---Divider---") 

The output of the above example is as follows:

First collaborative program execution output 1 10 foo Function output 2 main true 4 --Divider---- Second collaborative program execution output r main true 11 -9 ---Divider--- Third collaborative program execution output x y main true 10 End collaborative program ---Divider--- main false cannot resume dead coroutine ---Divider--- 

The above examples are as follows:

  • Call resume to wake up the collaborative program. If the resume operation is successful, return ‘true’. Otherwise, return ‘false’;

  • Collaborative program running

  • Run to yield statement

  • yield suspend the collaborative program for the first time resume return; (note: here yield return, the parameter is resume parameters of)

  • The second time resume , wake up the collaborative program again; (note: here resume except for the first parameter, the remaining parameters will be used as yield parameters of)

  • yield return

  • Collaborative programs continue to run

  • If the collaborative program used continues to run, it will continue to be called after completion. resume method outputs: cannot resume dead coroutine

resume and yield strength of the cooperation is that resume in the main program, it passes the external state (data) into thecollaborative program; and the yield internal state (data) is returnedto the main program.

4.25.4. Producer-consumer problem #

I’ll use it now. Lua collaborative program to complete the classic producer-consumer problem.

Example #

local newProductor function productor() local i = 0 while true do i = i + 1 send(i) -- Sending produced items to consumers end end function consumer() while true do local i = receive() -- Obtaining goods from producers print(i) end end function receive() local status, value = coroutine.resume(newProductor) return value end function send(x) coroutine.yield(x) -- X represents the value that needs to be sent, and once the value is returned, the collaborative program will be suspended end -- Start program newProductor = coroutine.create(productor) consumer() 

The output of the above example is as follows:

1 2 3 4 5 6 7 8 9 10 11 12 13 …… 
《地理信息系统原理、技术与方法》  97

最近几年来,地理信息系统无论是在理论上还是应用上都处在一个飞速发展的阶段。 GIS被应用于多个领域的建模和决策支持,如城市管理、区划、环境整治等等,地理信息成为信息时代重要的组成部分之一; “数字地球”概念的提出,更进一步推动了作为其技术支撑的GIS的发展。 与此同时,一些学者致力于相关的理论研究,如空间感知、空间数据误差、空间关系的形式化等等。 这恰好说明了地理信息系统作为应用技术和学科的两个方面,并且这两个方面构成了相互促进的发展过程。