The collaborative program in Lua is detailed _lua

Source: Internet
Author: User
Tags lua

Objective

A collaborative program is similar to a thread, a sequence of execution, with its own stack, local variables, and instruction pointers, while sharing global variables and most of the rest with other collaborative programs. Conceptually, the main difference between a thread and a collaboration program is that a program with multiple threads can run several threads at the same time, while a collaborative program needs to work together. That is, a program that has multiple concurrent programs can only run a single program at any one time, and a cooperating program that is running will only suspend execution when it explicitly asks to be suspended.

The foundation of collaborative procedures

LUA places all the functions on the collaboration program in a table called "Coroutine." function creation is used to create a new synergistic program, which has only one parameter, which is a function. The code for this function is what the collaborative program needs to do. Create returns a thread type value that represents the new collaboration program, and the general create parameter is an anonymous function, such as the following code:

Copy Code code as follows:

Local CO = coroutine.create (function () print (' Hello world ') end)

A collaborative program can have four different states: Suspend (suspended), run (running), Death (dead), and Normal (regular). When a new collaboration program is created, it is in a suspended state, and the implication is that the collaborative program does not automatically execute its content when it is created, and we can check the state of the collaboration program through the function status.

Copy Code code as follows:

Local CO = coroutine.create (function () print (' Hello world ') end)
Print (Coroutine.status (CO))--Suspended

function Coroutine.resume is used to start or restart the execution of a synergistic program and change its state from suspend to run:

Copy Code code as follows:

Local CO = coroutine.create (function () print (' Hello world ') end)
Print (Coroutine.status (CO))--Suspended
Coroutine.resume (CO)--Hello World

In the code above, I called the resume function to change the co-suspended to running state, and when the Hello World was printed, the CO program was in a dead state.

So far, a collaborative program is a function call. In fact, the real strength of a collaborative program is the use of function yield, which allows a running collaboration program to hang, and then can then resume its operation, such as the following code:

Copy Code code as follows:

Local CO = coroutine.create (function ()
For i = 1, the Do
Print ("Co", I)
Coroutine.yield ()
End
End

--Print Initial state
Print (Coroutine.status (CO))--Suspended

--Wake Collaborative program Co
Coroutine.resume (CO)--print Co 1

--Print the status of the collaborative program
Print (Coroutine.status (CO))--Suspended

--Wake up the CO program again
Coroutine.resume (CO)--Print CO 2

--Print the status of the collaborative program
Print (Coroutine.status (CO))--Suspended

Coroutine.resume (CO)--print Co 3
Coroutine.resume (CO)--print Co 4
Coroutine.resume (CO)--print Co 5
Coroutine.resume (CO)--print Co 6
Coroutine.resume (CO)--print Co 7
Coroutine.resume (CO)--print Co 8
Coroutine.resume (CO)--print Co 9
Coroutine.resume (CO)--print Co 10
Coroutine.resume (CO)--print Nothing
Print (Coroutine.status (CO))--dead
Coroutine.resume (CO)

When any error occurs in the execution of a synergistic program, LUA does not display the error message, but instead returns execution to the resume call. When the first return value of the Coroutine.resume is false, it indicates that the collaboration program is running in error, and when it is true, the collaboration program is working properly.

When a collaborative program a wakes up another program B, the collaboration program A is in a special state, either suspended (unable to continue execution of a) or run (b is running). So the state of this time is called the "normal" state.

The LUA Collaboration program also has a useful mechanism for exchanging data through a pair of Resume-yield. When the first call to resume, there is no corresponding yield waiting for it, so all the extra parameters passed to the resume are treated as arguments to the main function of the collaboration program. such as the following code:

When there is no yield in the collaboration program, the first call to resume, all the extra parameters passed to the resume will be considered as parameters for the main function of the collaboration program, such as the following code:

Copy Code code as follows:

Local CO = coroutine.create (function (A, B, c)
Print ("Co", A, B, c)
End

Coroutine.resume (Co, 1, 2, 3)--CO 1 2 3

When there is a yield in the collaborative program, everything becomes complicated, first to analyze the process:

1. Call resume and wake up the cooperative program;
2. Cooperative program operation;
3. Run to yield statement;
4.yield suspend the collaboration program, the first time resume return; (Note: Here yield returns, parameters are resume parameters)
5. Second resume, Wake up the collaborative program again; (note: In this resume parameter, in addition to the first argument, the remaining parameters will be used as yield parameters)
6.yield return;
7. The collaborative process continues to operate;

Here are some of the code from other blogs to illustrate the calling process above:

Copy Code code as follows:

function foo (a)
    print ("foo", a)  --Foo 2
    return Coroutine.yield (2 * a)--return 2 * An
End
 
Co = coroutine.create (funct Ion (A, b)
    print ("Co-body", A, b)--Co-body 1
    local r = foo (A + 1)
 
    print ("Co-body2", R)
    local r, s = Coroutine.yield (A + B, a -B
 
    print ("Co-body3", R, s)
    return B, ' end '
end)  
Print ("main", Coroutine.resume (Co, 1,)--True, 4
Print ("------")
Print ("main", Coroutine.) Resume (CO, "R"))--True 11-9
Print ("------")
Print ("main", Coroutine.resume (Co, "X", "Y"))--True br> Print ("------")
Print ("main", Coroutine.resume (Co, "X", "Y"))--false cannot resume dead coroutine
Print ( "------")

The output results are as follows:

Copy Code code as follows:

>lua-e "Io.stdout:setvbuf ' No" "Test.lua"
Co-body 1 10
Foo 2
Main true 4
------
Co-body2 R
Main true 11-9
------
Co-body3 x y
Main true Ten End
------
Main false cannot resume dead coroutine
------
>exit code:0

The strong thing about resume and yield is that resume is in the master, it passes the external state (data) inside the collaboration program, while yield returns the internal state (data) to the master.

Producer-Consumer issues

Now I'm using the LUA collaboration program to complete the producer-consumer classic issue. Producers produce things that consumers consume producers produce.

Copy Code code as follows:

Local Newproductor

function Productor ()
Local i = 0
While True
i = i + 1
Send (i)--sends the goods to the consumer
End
End

function consumer ()
While True
Local i = Receive ()--get the goods from the producer
Print (i)
End
End

function receive ()
Local status, Value = Coroutine.resume (newproductor)
return value
End

function Send (x)
Coroutine.yield (x)--X indicates the value that needs to be sent, and after the value returns, hangs the collaboration program
End

--Start the program
Newproductor = Coroutine.create (productor)
Consumer ()

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.