aardio多任務開發多線程線程池

職場菊菊子 2024-04-30 20:32:14

aardio作爲一門發展了17年的國産編程語言,自然具有通過多線程並行執行任務的能力。今天一起看看aardio如何執行多線程。

什麽是線程

要了解什麽是線程,需要先了解什麽是進程。進程是一個應用程序運行的最小單位。一個應用程序的進程在運行的時候,至少包括一個線程,通常稱之爲主線程,比如我們的窗體界面線程,一般就是主線程。一個應用程序除了主進程之外,可能會創建新的線程去執行一些執行起來比較慢的操作。應用程序此時就有了多個線程。

爲什麽用多線程

根據上面的介紹,使用多線程的目的很明確,提升應用程序處理多任務的並行能力,優化程序性能,讓程序運行更流暢更迅速。對于windows窗體程序而言,可以在處理複雜多任務的同時,窗體主界面不卡頓。

創建單個線程

aardio提供了幾種創建線程的方式。

thread.invoke(線程函數,其他參數)

創建線程但不返回線程句柄,線程句柄已自動關閉。注意線程函數有獨立的全局變量環境,線程引用的庫應當在線程函數內單獨導入。創建後線程會自動運行。

import win.ui;/*DSG{{*/var winform = win.form(text="多線程 —— 入門";right=536;bottom=325)winform.add(button={cls="button";text="啓動線程";left=27;top=243;right=279;bottom=305;db=1;dl=1;dr=1;font=LOGFONT(h=-16);z=1};edit={cls="edit";left=27;top=20;right=503;bottom=223;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=2})/*}}*/winform.button.oncommand = function(id,event){ //禁用按鈕並顯示動畫 winform.button.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"} //創建工作線程 thread.invoke( //線程啓動函數 function(winform){ for(i=1;3;1){ sleep(1000); //在界面線程執行 sleep 會卡住 //調用界面控件的成員函數 - 會轉發到界面線程執行 winform.edit.print("工作線程正在執行,時間:" + tostring( time() ) ); } winform.button.disabledText = null; },winform //窗口對象可作爲參數傳入工作線程 )}

thread.invokeAndWait(線程函數,其他參數)

調用並等待線程函數執行完畢,然後獲取此線程函數的返回值。在界面線程等待時界面仍可響應用戶操作,線程函數的返回值會返回給調用線程。線程函數擁有獨立的全局變量,並應遵守多線程調用規則。值得注意的是,前面介紹的thread.invoke不會返回執行結果。

參數@1指定的線程函數,

參數@1之後的其他可選參數會作爲調用線程函數的參數。

import win.ui;/*DSG{{*/var winform = win.form(text="aardio form";right=759;bottom=469)winform.add(button={cls="button";text="讀取網頁";left=272;top=368;right=624;bottom=440;z=1};edit={cls="edit";text="edit";left=48;top=40;right=720;bottom=336;edge=1;multiline=1;z=2})/*}}*/winform.button.oncommand = function(id,event){ winform.button.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"} winform.edit.text = thread.invokeAndWait( function(winform){ sleep(3000);//暫停模擬一個耗時的操作 import inet.http; return inet.http().get("http://www.aardio.com"); },winform ) winform.button.disabledText = null;}winform.show()win.loopMessage();線程池

給給個任務創建一個線程,看起來沒什麽問題。但是,當任務數量很多時,比如成百上千個,創建這麽多線程對于操作系統而言會造成很大開銷,頻繁在多線程切換反而會降低線程執行的性能。這時候,我們就需要創建線程池,管理多線程。

aardio給我們提供了兩種線程池方案,thread.works執行相同任務(相同的函數)和thread.manage執行不同任務(不同的函數)。兩者都可以指定線程池大小,新添加的任務從線程池裏面取線程執行任務。

分別看看案例。thread.manage案例:

import console;import thread.manage;//創建線程管理器manage = thread.manage(3);var thrdFunc = function(name){ import win; import console; for(i=1;10;1){ console.log( thread.getId(),name ) if( !win.delay(1000) ){ //主線程可以用 manage.quitMessage()中斷這個循環 console.log("收到退出指令") return; } } return 67;}//創建線程,如果線程池已滿會自動等待其他線程結束manage.create(thrdFunc,"線程1").onEnd = function(...){ console.log("線程1的回調",...);} //創建線程(忽略線程返回值),如果線程池已滿會自動等待其他線程結束manage.createLite(thrdFunc,"線程2").onEnd = function(){ console.log("線程2的回調");}manage.create(thrdFunc,"線程3");/*創建所有線程以後,必須調用 manage.waitClose() 函數等待所有線程執行完成,manage.waitClose() 也會負責觸發 onEnd 回調,並自動關閉已結束線程的線程句柄。*/manage.waitClose(); console.pause();

thread.works案例

import console;import thread.works;import time;var testWorksSameTask = function(){ var works = thread.works( 4, function(...) { import console; thread.lock("寫控制台") console.log("線程ID" + thread.getId(),",開始工作,接收到任務指令參數",...) thread.unlock("寫控制台") return "返回值,線程ID" + thread.getId(); } ); //分派任務 for(i=1;10;1){ works.push("task ->" + i) } //退出程序前,等待任務完成並關閉所有線程 works.waitClose( function(r){ console.log( "檢查成果", r ) } )}testWorksSameTask()execute("pause")
0 阅读:2

職場菊菊子

簡介:感謝大家的關注