lua協程

    協同程序與線程差很少,也就是一條執行序列,擁有本身獨立的棧、局部變量和指令指針,同時又跟其餘協同程序共享全局變量和其餘大部分東西。從概念上來說,線程與協同程序的主要區別在於:一個具備多線程的程序能夠同時運行幾個線程,而協同程序卻須要彼此協做的運行。就是說,一個具備多個協同程序的程序在任意時刻只能運行一個協同程序,而且正在運行的協同程序只會在其顯示的要求掛起時,它的執行纔會暫停。
多線程

    lua將全部關於協同程序的函數放置在一個名爲「coroutine」的table中,函數create用於建立新的血統程序,它只有一個參數,就是一個函數。該函數的代碼就是協同程序須要執行的內容。create會返回一個thread類型的值,用於表示新的協同程序,通常create的參數是一個匿名函數,如:
函數

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

    一個協同程序有四種不一樣的狀態:掛起(suspended)、運行(running)、死亡(dead)和正常(normal)。當新建立一個協同程序時,它處於掛起狀態,也就是說,協同程序不會在建立它的時候自動運行。咱們能夠經過函數status來檢查協同程序的狀態。lua

local co = coroutine.create(function()
    print("hi")
end)
print(coroutine.status(co))    --suspended

    函數coroutine.resume用於啓動或再次啓動一個協同程序的執行,並將其狀態由掛起改成運行。線程

local co = coroutine.create(function()
    print("hi")
end)
print(coroutine.status(co))    --suspended
coroutine.resume(co)    --hi

    上面的代碼中調用來resume函數,將協同程序co由suspended改成running狀態,當打印了hi以後,co就處於死亡狀態了。
指針

    咱們如今來看一下協程函數的yield,該函數可讓一個運行中的協同程序掛起,而以後能夠再恢復它的運行。看下面的例子:code

local co = coroutine.create(function()
	for i=1,5 do 
		print(i)
		coroutine.yield()
	end
end)

print(coroutine.status(co))
coroutine.resume(co)

print(coroutine.status(co))
coroutine.resume(co)

print(coroutine.status(co))
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
--coroutine.resume(co)注意這句話
print(coroutine.status(co))
coroutine.resume(co)

   輸出:orm

suspended
1
suspended
2
suspended
3
4
5
suspended    --當把上面的註釋打開,這是輸出爲:dead

    在最後一次調用resume時,協同程序的內容已經執行完畢,並已經返回。所以,這時協同程序處於死亡狀態。當在協同程序的執行中發生任何錯誤,Lua是不會顯示錯誤消息的,而是將執行權返回給resume調用。當coroutine.resume的第一個返回值爲false時,就代表協同程序在運行過程當中發生了錯誤;當值爲true時,則代表協同程序運行正常。協程

    當一個協同程序A喚醒另外一個協同程序B時,協同程序A就處於一個特殊狀態,既不是掛起狀態(沒法繼續A的執行),也不是運行狀態(是B在運行)。因此將這時的狀態稱爲「正常」狀態。io

    Lua的協同程序還具備一項有用的機制,就是能夠經過一對resume-yield來交換數據。在第一次調用resume時,並無對應的yield在等待它,所以全部傳遞給resume的額外參數都視爲協同程序主函數的參數。table

    當協同程序中沒有yield時,第一次調用resume,全部傳遞給resume的額外參數都將視爲協同程序主函數的參數,如如下代碼:

local co = coroutine.create(function (a, b, c)
     print("co", a, b, c)
end)

coroutine.resume(co, 1, 2, 3)     -- co 1 2 3

    在resume調用返回的內容中,第一個值爲 true則表示沒有錯誤,然後面全部的值都是對影yield傳入的參數:

local co = coroutine.create(function(a,b)
	coroutine.yield(a+b,a-b)
end)
print(coroutine.resume(co,20,10))

    輸出:

true	30	10

    於此對應的時,yield返回的額外值就是對應resume傳入的參數:

local co = coroutine.create(function()
	print(coroutine.yield())
end)
coroutine.resume(co)
coroutine.resume(co,4,5)

    輸出:

4	5

    最後,當一個協同程序結束時,它的主函數所返回的值都將做爲對應resume的返回值:

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

    輸出:

true	6    7
相關文章
相關標籤/搜索