分享

aardio多線程開發入門教程

 ipilipala 2016-12-31
在aardio中使用多線程非常簡單,實際上只要掌握一些最基礎的語法知識、線程概念就可以了,如果掌握這種基礎知識的能力都沒有,去寫軟件是不可思議的事,因為軟件開發就是大腦的一種極限運動 - 擁有良好的自學能力是最基本的底線。

最簡單的創建一個線程:
import console;

//創建一個線程
thread.invoke(
   
function(){
        
return 123;
    }
)

console.pause(
true);

thread.invoke創建一個線程,參數是一個函數對象 - 這個函數也就是新線程的執行代碼。


相信你知道,上面的代碼還可以改成這樣:
線程函數 = function(){
   
return 123;
}

thread.
invoke( 線程函數 ) //創建一個線程

評分

參與人數 1銀幣 +5 收起 理由
12388 + 5 很給力!

查看全部評分

36

主題

741

帖子

4401

積分

超級版主

Rank: 8Rank: 8

積分
4401
沙發
 樓主| 發表於 2015-11-16 18:41:41 | 只看該作者

也許你會遇到一個白痴,他會把我上面的代碼改成這樣: [quote]線程函數 = [color=#0000ff]function[/color][color=#

也許你會遇到一個白痴,他會把我上面的代碼改成這樣:
線程函數 = function(){
   
return 123;
}

thread.
invoke( 線程函數( )  )  
他自作聰明的在上面加了一個括號,以至於在創建線程以前就執行了函數,
結果上面的代碼最後實際上變成了
thread.invoke( 123 )  
千萬不要這麼蠢的去寫代碼,如果你寫過這樣的代碼,我建議你別在編程這個事情上浪費時間了,去工地搬磚吧!

36

主題

741

帖子

4401

積分

超級版主

Rank: 8Rank: 8

積分
4401
板凳
 樓主| 發表於 2015-11-16 19:09:17 | 只看該作者

線程可以分為界麵線程、工作線程。界麵線程簡單的你可以理解包含 [font=新宋體][size=14px]winform.show(); [/size][/fon

線程可以分為界麵線程、工作線程。界麵線程簡單的你可以理解包含 winform.show(); win.loopMessage(); 這種創建窗口,顯示用戶界面的線程,反之則稱為工作線程。界麵線程通常都會有 win.loopMessage() 這麼一句代碼用於啟動界麵線程的消息循環,這個 win.loopMessage() 就像人的心跳一樣 - 他一停止界麵線程也就玩完了。

注意界麵線程本身是一個獨立的線程,不要在工作線程中去直接操作界麵線程中的窗口對象這些,
而且在所有線程中你都不要直接去操作另一個線程的對象,你需要瞭解一些最基本的線程間打交道的規則。

打個比方:多線程就像多個在並列的軌道上疾馳的火車,
你要在A火車上與B火車上的人交互,或者你想讓B火車上的人幹什麼,你要注意以下四個規則:

1、你不能直接無保護的操作其他線程中的對象,這相當於在火車飛馳的時候,你冒著被撕碎的危險伸手到另一部火車上去操作點什麼,aardio中你不能進行如此愚蠢的行為,這是被禁止的,你沒辦法做到這一點。

2、任何多線程需要用到的公共代碼,都需要放到庫模塊裡,並且可以使用 import 導入線程,在一個線程中import的庫模塊不等於在另一個線程中你就不用再 import,這就好像給火車加油,油箱是公用的,但是哪個火車需要油需要自己去import,你給A火車加油不等於B火車就不用加油了。

3、你可以在創建線程的時候給另外一個線程傳遞啟動參數,這相當於在火車還沒有啟動以前,一部火車上的人給另一部火車上的人送點東西,這是安全的,用代碼來講就是這樣寫:
thread.invoke( 線程函數,"給你的","這也是給你的","如果還想要上車後打我電話" )
4、在線程啟動以後,你需要通過 thread.command 發送命令給其他線程、或者響應其他線程的命令消息,這相當於你在一部火車上給另一部火車上的人打電話,讓他做點什麼操作(而不是從車窗中把你的手或頭伸到另一部火車上親自去操作),這用代碼來演示下就是這樣寫:
import win.ui;
/*DSG{{*/
var winform = win.form(text="線程命令";right=599;bottom=399)
winform.add(
edit={cls=
"edit";left=12;top=11;right=588;bottom=389;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=1}
)
/*}}*/

import thread.command;
var listener = thread.command();
listener.print =
function( ... ){
    winform.edit.print( ... )
//我們在界麵線程中這樣響應工作線程的消息
}

//創建工作線程
thread.invoke(

   
function(){
   
        
//必須在線程函數內部導入需要的庫
        import thread.command;
        
        
//調用界麵線程的命令
        thread.command.print("hello world",1,2,3);
        
    }
)


winform.show();
win.loopMessage();

非常簡單是吧?你只要遵守多線程的基本交通規則,那麼你使用 aardio 寫多線程的代碼就會非常的快樂。你基本上很少會遇到很多線程的痛苦問題,這些痛苦的問題aardio都幫你解決好了。

當然,如果你的思維方式是:「我就是要在工作線程中直接操作界麵線程的 winform 什麼的」,那這麼就會很痛苦了 - 因為:「aardio就是不讓你這麼做!」,我曾經看到某人,他在界麵線程中創建了一個 web.form ,然後創建了很多的工作線程 - 再削尖腦殼的想辦法掛接上去操作 web.form,他以為這樣就聰明的繞過了aardio給他的限制,這樣會讓界麵線程跑的更快,其實這是讓界麵線程跑的更慢,而且讓界麵線程變的非常不穩定且容易崩潰。而且這傢伙用了好幾年的時間執著於研究這種技術,例如他修改一個界面上文本框的值,他不直接寫 winform.edit.text = "文本值",他會寫一大堆的代碼創建一個線程再 winex.find() 查找窗口,查找到窗口以後再通過句柄用寫模擬輔助的方式去修改一個文本框的值,實在是愚昧不可救藥!

讓多個線程去操作界麵線程的對象,這就相當於你把火車上的人都喊下車了,張三抱個輪子往前跑,李四跑個車廂往前跑,這並不能讓你這部火車跑的比其他火車更快,只會讓你這部火車變的混亂痛苦。

你不能這樣搞,一定要遵守秩序和規則,例如大家坐火車,不能你覺得到站了就從車窗往下跳,他覺得到站了就從車窗往下跳,這是不可以的,你必須先去登記,你要在A站下車,他要在B站下車,到站以後自覺排隊,輪到你了再排隊下車。上車也一樣,你不能看到火車來了就往上跳,你得先去買票登記,火車到站了以後,你再排隊上車。這個排隊上下車的機制在 aardio 裡就是 thread.command。

所以大家要理解第一原則:在 aardio 裡寫多線程代碼,首先就是要學會並且必須要學會運用 thread.command,不用 thread.command 去寫多線程代碼,就好比坐火車不買票 - 那是耍流氓!

點評

真棒: 5.0 繼續努力: 5.0
同意: 5.0
同意: 5 真棒: 5
太好了,解決了我疑惑,非常感謝!  發表於 2015-12-1 09:36
真棒: 5 繼續努力: 5
  發表於 2015-11-17 08:52

36

主題

741

帖子

4401

積分

超級版主

Rank: 8Rank: 8

積分
4401
地板
 樓主| 發表於 2015-11-16 19:14:09 | 只看該作者

再簡單總結一下寫多線程代碼的四個規則: [align=left][font=新宋體]1、你不能在一個線程中直接訪問另一個線程的對象 [color=#

再簡單總結一下寫多線程代碼的四個規則:

1、你不能在一個線程中直接訪問另一個線程的對象

import fsys;
thread.
invoke(
   
function(){
        
// 你不能直接訪問外部線程的對象,例如前面在主線程中導入的fsys
        fsys.createDir("/test");
    }
)

2、任何多線程需要用到的公共代碼,都需要放到庫模塊裡,線程需要用到的庫模塊都需要在對應線程中導入。

import fsys;
thread.
invoke(
   
function(){
   
        
//每個線程要自己導入自己要用的庫模塊
        import fsys;
        
        
//這時候你就可以使用fsys了
        fsys.createDir("/test");
    }
)

2、你可以在創建線程的時候給另外一個線程傳遞啟動參數。

thread.
invoke(
   
/*
        注意不要試圖繞過前面的第一原則,
        不能把winform,fsys這種有函數成員的對象作為線程啟動參數,
        如果你通過線程啟動參數傳給線程一個函數對象,這個函數必須符合線程函數的所有規則(例如不能訪問其他線程的對象)
    */

   
function(a,b,c){
        
    },
"參數",123,{ 456 } //這三個參數會傳給線程的啟動參數a,b,c,
)

4、在線程啟動以後,多線程間的交互必須使用 thread.command。
這一條就不再舉例了,請看前面的例子。


重要提醒: 線程中的運行時錯誤信息會輸出到控制台(而不是象主線程那樣彈出錯誤對話框),所以多線程應用程序在開發時需要打開控制台查看錯誤信息。


36

主題

741

帖子

4401

積分

超級版主

Rank: 8Rank: 8

積分
4401
5#
 樓主| 發表於 2015-11-16 21:05:56 | 只看該作者

最基礎的方式是通過創建線程返回的線程句柄管理線程,入門示例: [quote] [align=left][font=新宋體][color=#008000]//

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多