Lua 協程

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的協助一下了


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445003.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

leetcode16 最接近的三數之和

給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。 例如,給定數組 nums [-1,2,1,-4], 和 target 1…

LINUX下動態鏈接庫的使用-dlopen dlsym dlclose dlerror

dlopen 基本定義   功能&#xff1a;打開一個動態鏈接庫 包含頭文件&#xff1a; #include <dlfcn.h> 函數定義&#xff1a; void * dlopen( const char * pathname, int mode ); 函數描述&#xff1a; 在dlopen的&#xff08;&#xff09;函數以指定模式打開指定的動…

leecode11 盛水最多的容器

給定 n 個非負整數 a1&#xff0c;a2&#xff0c;...&#xff0c;an&#xff0c;每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n 條垂直線&#xff0c;垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。找出其中的兩條線&#xff0c;使得它們與 x 軸共同構成的容器可以容納最多…

Github(2)-本地配置git

本地配置git1.注冊賬號2.安裝git工具3.配置git 賬號1.注冊賬號 github網頁注冊github賬戶 2.安裝git工具 本地安裝git工具 step1 查看是否安裝git git version step2 mac 安裝 brew install git step2 linux安裝 sudo apt-get install git 3.配置git 賬號 創建ssh key, 配置…

lua面向對象編程之點號與冒號的差異詳細比較

首先,先來一段在lua創建一個類與對象的代碼 Class {}Class.__index Classfunction Class:new(x,y)local temp {}setmetatable(temp, Class)temp.x xtemp.y yreturn tempendfunction Class:test()print(self.x,self.y)endobject Class.new(10,20)object:test() 猜一下會輸…

lua __index __newindex upvalue 示例

項目中有個公會對象&#xff0c;數據大部分存在data中&#xff0c;之前都是 u.data.point這樣訪問&#xff0c;太麻煩了。 于是通過設置__index 使之可以直接訪問屬性&#xff0c;u.point。 但是還是不能直接改屬性&#xff0c;u.point 4&#xff0c;所以再設置了__newindex…

leecode26 刪除排序數組中的重復項

給定一個排序數組&#xff0c;你需要在原地刪除重復出現的元素&#xff0c;使得每個元素只出現一次&#xff0c;返回移除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須在原地修改輸入數組并在使用 O(1) 額外空間的條件下完成。 示例 1: 給定數組 nums [1,1,2…

MachineLearning(6)-Daviad Silver強化學習課程脈絡整理

強化學習-Daviad Silver強化學習課程脈絡整理1.lecture1 introduction1.1 強化學習簡介1.2 強化學習類別1.3 強化學習的主要問題2.lecture2 Markov Decision Process2.1 MP,MRP,MDP2.2 Bellman Eqution--貝爾曼方程2.3 Bellman Eqution--貝爾曼期望方程2.4 最優策略2.5 最優值函…

lua的VS或者VC環境的搭建調試

安裝完LuaForWindows_v5.1.4 打開vs tools->options->projects->directories executable files 選項添加lua安裝以后的路徑,我的是 C:\Program Files\Lua\5.1 include files選項添加lua include路徑,我的是 C:\Program Files\Lua\5.1include library files 選項添…

leecode53 最大子序列和

給定一個整數數組 nums &#xff0c;找到一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大&#xff0c;為 6。 思路&#xff1a;…

在頁游中LUA的應用(1)

通常,你希望在你的游戲開始的時候讀取一些信息,以配置你的游戲,這些信息通常都是放到一個文本文件中,在你的游戲啟動的時候,你需要打開這個文件,然后解析字符串,找到所需要的信息。 或許你認為這樣就足夠了,為什么還要使用Lua呢? 應用于“配置”這個目的,Lua提供給你…

Github(3)-本地文件管理

使用github 托管代碼簡單使用教程--本地文件管理1.基本概念2.本地文件管理2.1 git add2.2 git status2.3 git commit2.3 git log2.5 git reset --hard 版本回退2.6 git reflog2.7 git diff2.8 git checkout --file 工作區文件恢復2.9 git rm 刪除版本庫里的文件廖雪峰老師博文學…

linux 中阻塞與非阻塞 同步與異步

簡單點說: 阻塞就是干不完不準回來&#xff0c; 非阻塞就是你先干&#xff0c;我先看看有其他事沒有&#xff0c;完了告訴我一聲。 我們拿最常用的send和recv兩個函數來說吧。比如你調用send函數發送一定的Byte,在系統內部send做的工作其實只是把數據傳輸(Copy)到TCP/IP協議棧…

leecode62 不同路徑

示例 1: 輸入: m 3, n 2 輸出: 3 解釋: 從左上角開始&#xff0c;總共有 3 條路徑可以到達右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右 示例 2: 輸入: m 7, n 3 輸出: 28 思路&#xff1a;太過于簡單&#xf…

數據庫的查詢優化建議整理

從大多數數據庫應用系統的實例來看,查詢操作在各種數據庫操作中所占據的比重最大,而查詢操作所基于的SELECT語句在SQL語句中又是代價最大的語句。 查詢語句(SELECT)的優化建議 (1)、合理使用索引:where子句中變量順序應與索引字鍵順序相同。 如:create index test_idx…

Github(4)-遠程操作

使用github 托管代碼簡單使用教程--遠程操作3.連接本地倉庫與遠程倉庫3.1 git clone 克隆實現鏈接3.2 git remote add origin4.遠程操作4.1 git checkout -b 切換分支14.2 git branch 查看分支4.3 git merge 合并分支4.3.1 step1&#xff1a;切換成主分支4.3.2 step2&#xff1…

leetcode64 最小路徑和

給定一個包含非負整數的 m x n 網格&#xff0c;請找出一條從左上角到右下角的路徑&#xff0c;使得路徑上的數字總和為最小。 說明&#xff1a;每次只能向下或者向右移動一步。 示例: 輸入: [ [1,3,1], [1,5,1], [4,2,1] ] 輸出: 7 解釋: 因為路徑 1→3→1→1→1 的總…

online游戲服務器架構--網絡架構

啟動&#xff1a;父進程啟動&#xff1b;子進程啟動&#xff1b;網絡架構。 每個父進程攜帶N個子進程&#xff0c;子進程負責處理業務邏輯和其它數據&#xff0c;而父進程只是將客戶端的請求路由到各個子進程&#xff0c;路由的策略非常簡單&#xff0c;父進程將請求包按照輪流…

online游戲服務器架構—用戶登錄數據組織 .

sprite_t類型的數據結構是核心數據結構&#xff0c;每一個登錄用戶對應一個&#xff0c;它的初始化在用戶登錄的時候&#xff0c;此后一直到用戶退出或者離線一直保存在系統內存當中&#xff0c;在此過程中該sprite_t數據結構被保存在兩個哈希表當中&#xff0c;一個是以用戶的…

leetcode300 最長上升子序列

經典題&#xff0c;不解釋&#xff0c;可以看我之前文章。 普通dp public class Solution {public int lengthOfLIS(int[] nums) {if (nums.length 0) {return 0;}int[] dp new int[nums.length];dp[0] 1;int maxans 1;for (int i 1; i < dp.length; i) {int maxval …