Lua里的協程是一個原來沒見過的東西,Python的Gevent也是一個基于coroutine的python網絡開發框架。性能據說很不錯。
協同的一個關鍵特征是它可以不斷顛倒調用者與被調用者之間的關系
協程和一般多線程的區別是,一般多線程由系統決定該哪個線程執行,是搶占式的,而協程是由每個線程自己決定自己什么時候不執行,并把執行權主動交給下一個線程。 協程是用戶空間線程,操作系統其存在一無所知,所以需要用戶自己去做調度,用來執行協作式多任務非常合適。
線程和協同程序的主要不同在于:在多處理器情況下,多線程程序同時運行多個線程;而協同程序是通過協作來完成,在任一指定時刻只有一個協同程序在運行,并且這個正在運行的協同程序只在必要時才會被掛起。這樣Lua的協程就不能利用現在多核技術了。
Lua 協程有三個狀態:掛起態(suspended)、運行態(running)、停止態(dead)。可以通過coroutine.status來查看協程出于神馬狀態。
創建一個協程需要調用coroutine.create 。它只接收單個參數,這個參數是 coroutine 的主函數。 create 函數僅僅創建一個新的coroutine 然后返回一個類型為thread的對象,并不會啟動 coroutine 的運行。
>hxc=coroutine.create(function () print("hi coroutine") end)
>print(type(hxc)) -->thread
>print(coroutine.status(hxc)) -->suspended
>coroutine.resume(co) --> hi coroutine ;函數coroutine.resume使協同程序由掛起狀態變為運行態,執行完畢協程進入dead狀態
>print(coroutine.status(hxc)) -->dead
調用 coroutine.resume 時,傳入的第一個參數就是 coroutine.create 的返回值。這時,coroutine 從主函數的第一行開始運行。接下來傳入 coroutine.resume 的參數將被傳進 coroutine 的主函數。在 coroutine 開始運行后,運行到自身終止或是遇到一個 yield調用,這個yield函數是協程特別之處,它可以將正在運行的代碼掛起。
hxc=coroutine.create(function ()
????for i=1,10 do
???????print("iter", i)
???????coroutine.yield()
????end
end)
執行這個協同程序,程序將在第一個yield處被掛起:
coroutine.resume(hxc) --> iter 1
print(coroutine.status(hxc)) --> suspended
執行
coroutine.resume(hxc) --> iter 2;resume激活被掛起的程序,將從函數yield的位置繼續執行程序,直到再次遇到yield或程序結束。
Lua中協同可以通過resume-yield來交換數據。
1)通過resume把參數傳遞給協同的主程序。
hxc = coroutine.create(function (a,b)
????print("hxc", a,b,c)
end)
coroutine.resume(hxc, 1, 2) --> hxc 1 2
2)數據通過yield傳給resume。true表明調用成功,true之后的部分,即是yield的參數。
hxc = coroutine.create(function (a,b)
????coroutine.yield(a + b, a - b)
end)
print(coroutine.resume(hxc, 20, 10)) --> true 30 10
或者把resume的參數,會被傳遞給yield。
hxc = coroutine.create (function ()
????print("hxc", coroutine.yield())
end)
coroutine.resume(hxc)
coroutine.resume(hxc, 4, 5) --> hxc 4 5
協程的用途最明顯的地方是需要訪問某個異步的功能時,C語言常采用回調的方法:當異步完成時,回調腳本的一個已知的函數。如果程序執行到異步點時,跳回,當異步完成后,再回到跳回點繼續執行。我的理解就是協程是把異步過程,當作同步處理。
這個還要仔細體會下~
Lua里面么有多線程,看來要靠C的協助一下了
協同的一個關鍵特征是它可以不斷顛倒調用者與被調用者之間的關系
協程和一般多線程的區別是,一般多線程由系統決定該哪個線程執行,是搶占式的,而協程是由每個線程自己決定自己什么時候不執行,并把執行權主動交給下一個線程。 協程是用戶空間線程,操作系統其存在一無所知,所以需要用戶自己去做調度,用來執行協作式多任務非常合適。
線程和協同程序的主要不同在于:在多處理器情況下,多線程程序同時運行多個線程;而協同程序是通過協作來完成,在任一指定時刻只有一個協同程序在運行,并且這個正在運行的協同程序只在必要時才會被掛起。這樣Lua的協程就不能利用現在多核技術了。
Lua 協程有三個狀態:掛起態(suspended)、運行態(running)、停止態(dead)。可以通過coroutine.status來查看協程出于神馬狀態。
創建一個協程需要調用coroutine.create 。它只接收單個參數,這個參數是 coroutine 的主函數。 create 函數僅僅創建一個新的coroutine 然后返回一個類型為thread的對象,并不會啟動 coroutine 的運行。
>hxc=coroutine.create(function () print("hi coroutine") end)
>print(type(hxc)) -->thread
>print(coroutine.status(hxc)) -->suspended
>coroutine.resume(co) --> hi coroutine ;函數coroutine.resume使協同程序由掛起狀態變為運行態,執行完畢協程進入dead狀態
>print(coroutine.status(hxc)) -->dead
調用 coroutine.resume 時,傳入的第一個參數就是 coroutine.create 的返回值。這時,coroutine 從主函數的第一行開始運行。接下來傳入 coroutine.resume 的參數將被傳進 coroutine 的主函數。在 coroutine 開始運行后,運行到自身終止或是遇到一個 yield調用,這個yield函數是協程特別之處,它可以將正在運行的代碼掛起。
hxc=coroutine.create(function ()
????for i=1,10 do
???????print("iter", i)
???????coroutine.yield()
????end
end)
執行這個協同程序,程序將在第一個yield處被掛起:
coroutine.resume(hxc) --> iter 1
print(coroutine.status(hxc)) --> suspended
執行
coroutine.resume(hxc) --> iter 2;resume激活被掛起的程序,將從函數yield的位置繼續執行程序,直到再次遇到yield或程序結束。
Lua中協同可以通過resume-yield來交換數據。
1)通過resume把參數傳遞給協同的主程序。
hxc = coroutine.create(function (a,b)
????print("hxc", a,b,c)
end)
coroutine.resume(hxc, 1, 2) --> hxc 1 2
2)數據通過yield傳給resume。true表明調用成功,true之后的部分,即是yield的參數。
hxc = coroutine.create(function (a,b)
????coroutine.yield(a + b, a - b)
end)
print(coroutine.resume(hxc, 20, 10)) --> true 30 10
或者把resume的參數,會被傳遞給yield。
hxc = coroutine.create (function ()
????print("hxc", coroutine.yield())
end)
coroutine.resume(hxc)
coroutine.resume(hxc, 4, 5) --> hxc 4 5
協程的用途最明顯的地方是需要訪問某個異步的功能時,C語言常采用回調的方法:當異步完成時,回調腳本的一個已知的函數。如果程序執行到異步點時,跳回,當異步完成后,再回到跳回點繼續執行。我的理解就是協程是把異步過程,當作同步處理。
這個還要仔細體會下~
Lua里面么有多線程,看來要靠C的協助一下了