Introduction to Lua programming coroutine

Source: Internet
Author: User

1. Introduction to Lua coroutine

Coroutine (coroutine), which is a collaboration routine, was first proposed and implemented by Melvin Conway in 1963. Unlike threads in mainstream programming languages, threads are intrusive components. The thread-implemented system is called a preemptible multi-task system, while the multi-task system implemented by coroutine becomes a collaborative multi-task system. Due to the lack of yield semantics, scheduling, sleep suspension, context switching, and other system overhead are inevitable during the running process. You also need to be careful to use the synchronization mechanism to ensure the normal operation of multithreading. The coroutine running command series are fixed and do not require a synchronization mechanism. switching between coroutines only involves the exchange of control. Compared with the thread, it is very lightweight. However, multiple threads can run at the same time, but only one route can run.

Coroutine has two important features:

1. Private data remains valid during the continuous operation of the coroutine

2. The coroutine gives control after each yield operation and continues execution from the stop point after being resume.

In layman's terms, it is more like a function with static data and multiple entry points and return points. The following is a simple example to look at this nature:

co = coroutine.create(function(a)  print("a = "..a)  c = coroutine.yield(a+1)  print("c = "..c)  return c*2end)_, b = coroutine.resume(co, 1)print("b = "..b)_, d = coroutine.resume(co, b )print("d = "..d)

Running result:

A = 1

B = 2

C = 2

D = 4

In addition to the entry point (function entrance) and return point (function end) of a common function, coroutine Co also has an entry point and return point in yield. When the main program resume for the first time, it passes 1 to parameter A. When it runs to yield, the coroutine returns control to the main program and provides the return value through the yield parameter. Therefore, B = a + 1, resume again, the main program passes the data to the CO variable C through parameter B, so as to enter the function from the second entry point, and finally return the value C * 2 to D.

The coroutine of resume/yield semantic implementation is an asymmetric coroutine. In an asymmetric coroutine, the relationship between the caller and the called is fixed. The caller transfers the control to the called through resume, the called user can only return to the caller through yield, but not to other coroutines. For example, a resume B resume C and C yield can only be a but not a or other coroutine.

Everything in the world is opposite and unified. Since there is an asymmetric coroutine, of course there is a symmetric coroutine. The symmetric coroutine has only one semantics that can directly transfer the control flow to the target coroutine.

The expression capability of asymmetric coroutine and symmetric coroutine is the same. Lua only implements asymmetric coroutine. One important reason is that Lua is implemented by C, the call and called relationship of asymmetric coroutine is very similar to that of function call of C, which facilitates extension programming of Lua and C.

Ii. coroutine practice

The following example uses coroutine to implement a classic producer-consumer model.

count = 10productor = coroutine.create(   function ()     i = 0     while(true) do       i = i+1       coroutine.yield(i)     end   end ) consumer = coroutine.create( function(co)   n = 1   while(n<count) do   _, v = coroutine.resume(co)     print(v)     n = n+1   end end ) coroutine.resume(consumer, productor)

Consumer starts productor. After productor generates an item, it returns it to consumer through yield, and then suspends it to wait for consumer to resume next time, which is very simple and intuitive.

Another important role of coroutine is to serve as an iterator that accesses data structures in turn. The following code shows how to access a binary tree in sequence.

l = {   v = 1,   left = nil,   right = nil, } r = {   v = 2,   left = nil,   right = nil, } root = {   v = 3,   left = l,   right = r, } preorder = function(root)   if(root == nil) then return end   coroutine.yield(root.v)   preorder(root.left)   preorder(root.right) end preco = coroutine.create(preorder) view = function(co, root)   state, v = coroutine.resume(co, root)   if(state == false) then return end   print(v)   while(true)  do     state, v = coroutine.resume(co)     if(state == false or v == nil) then return end     print(v)   end end view(preco, root)

For coroutine, the implementation principle of a very lightweight coroutine is introduced here. Yunfeng uses uconext to implement a coroutine library similar to Lua. If you are interested, you can study it.

Reference:

Coroutines in C

Introduction to Lua programming coroutine

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.