天天看點

Tolua使用筆記四:lua中的多線程與數組的擷取

案例七:

在這裡,總有種被作者套路的趕腳,衆所周知,在Lua中不存在那種傳統意義上的多線程,所謂的多線程都是基于協程而實作的,是以Lua中的線程也都隻是那種協作式的多線程,而無法實作那種搶占式的多線程的效果,這也就導緻有些效果我們無法得到實作~~~

如果有的時候真的需要那種搶占式的效果,可以考慮使用我之前提到的那個tolua的作者封裝過的協程,功能上趕腳幾乎可以替代真正的那種搶占式多線程了

在這個案例之中,其實主要可以學到的就是如何擷取到原生的lua線程,并在C#端進行lua線程的挂起,激活等操作

主要核心代碼如下:

string script =
        @"
            function fib(n)
                local a, b = 0, 1
                while n > 0 do
                    a, b = b, a + b
                    n = n - 1
                end
                return a
            end

            function CoFunc(len)
                print('len = '..len)
                print('Coroutine started')                
                local i = 0
                for i = 0, len, 1 do                    
                    local flag = coroutine.yield(fib(i))					
                    if not flag then
                        break
                    end                                      
                end
                print('Coroutine ended')
            end

            function Test()                
                local co = coroutine.create(CoFunc)                                
                return co
            end            
        ";

    LuaState state = null;
    //lua線程類型
    LuaThread thread = null;

	void Start () 
    {
        //初始化Lua虛拟機
        state = new LuaState();
        state.Start();
        state.LogGC = true;
        state.DoString(script);

        //從虛拟機中擷取到lua函數對象
        LuaFunction func = state.GetFunction("Test");
        func.BeginPCall();
        func.PCall();
        thread = func.CheckLuaThread();   //擷取對應的線程對象
        thread.name = "LuaThread";
        func.EndPCall();
        func.Dispose();
        func = null;

        thread.Resume(10);    //運作線程并同時傳遞參數10
	}
           

順便值得說的一句就是,在對lua線程操作的時候,還要在C#的Update中調用如下代碼

void Update()
    {
        state.CheckTop();
        state.Collect();
    }
           

貌似是用于垃圾回收的作用,我大概記得之前也是這個用法,這裡暫且留個坑,如果坑了回頭一定會補

核心函數:

int Resume(params object[] args)
           

該方法為thread的内置公有方法,主要作用等同于lua中的

coroutine.resume()
           

這樣說應該基本上都可以懂了吧,如果還是不了解,請回去好好看一下《lua程式設計》中關于協程的那一章

最後還是想補一句,作者對于這種協作式多線程總的而言還是不甚滿意,後期有機會作者将會嘗試直接在lua引入C#的多線程以及鎖機制,具體的方案等我做出來再說

案例8:

這個部分感覺還是相當有用處的,主要是介紹了對于C#中的數組對象的基本的幾種通路方法

核心代碼全部在那段lua代碼中:

function TestArray(array)
                local len = array.Length
                print('直接輸出')
                for i = 0, len - 1 do
                    print('Array: '..tostring(array[i]))
                end
                
                print('轉Table表後輸出')
                local t = array:ToTable()                
                
                for i = 1, #t do
                    print('table: '.. tostring(t[i]))
                end

                local iter = array:GetEnumerator()

                while iter:MoveNext() do
                    print('iter: '..iter.Current)
                end

                local pos = array:BinarySearch(3)
                print('array BinarySearch: pos: '..pos..' value: '..array[pos])

                pos = array:IndexOf(4)
                print('array indexof 4 pos is: '..pos)
                
                return 1, '123', true
            end
           

在這裡,我們可以得出如下幾部分結論:

1 :對于C#中的數組,在lua中,我們可以直接通過下标索引通路,寫法形式與C#中完全一緻,例如: array[i] , 同時還可以通過直接調用 array.Length 擷取到數組的大小,感覺對于這類通路作者已經做的使用極度友善了

2:對于C#中的數組,我們可以調用 array:ToTable() 實作将數組對象轉化為對應的lua中的Table表的形式

3:第3中通路方式我也不是很熟悉,好像是将其轉化成疊代器格式,具體方法為 array:GetEnumerator()  ,通路元素的時候可以通過調用 iter:Current 來擷取到,通過使用方法iter:MoveNext() 來将疊代器的所指位置移至下一個

4:除了上述的方法之外,可以通過方法  array:BinarySerach(元素下表位置) 的方法來擷取到數組對應位置的元素

     調用方法 array:IndexOf(資料值)  的方法擷取到指定元素的下标的值

實際效果圖如下:

Tolua使用筆記四:lua中的多線程與數組的擷取
Tolua使用筆記四:lua中的多線程與數組的擷取

以上也就是整個案例8的全部知識點了,

最近找工作的事情終于有了着落,在剩下的一點學生時代,有機會還是乘着這段時間來回憶一下過去所學,留下點東西,也算是了卻一樁心願了

繼續閱讀